accesspatterns.dev
← All models

helpdesk

Support Ticket Queue

A worklist that maintains itself, because closing a ticket leaves the index.

Open tickets carry an index key; closed ones do not. The result is an index containing exactly the open work, that nothing has to maintain. Closing a ticket removes its index attributes and the row leaves on its own, with no sweep and no second write to a queue table.

The model

Ticket

One support ticket. Only the open ones are in the index.

pk
TICKET#<ticketId>

Attributes: subject (S), status (S), assignee (S), openedAt (N), GSI1PK (S), GSI1SK (S)

Access patterns

  • Query · GSI1The open queue

    Every open ticket, oldest first, from an index holding nothing else.

  • UpdateItemClose a ticket

    Set the status and remove the index keys, which takes it out of the queue.

  • GetItemRead one ticket

    A single ticket by id.

Design notes

The index is small because most rows are not in itwhy

A secondary index only holds items that have its key attributes. Closed tickets have none, so they are absent - not filtered out on read, absent. A helpdesk with a million closed tickets and forty open ones has an index of forty, and the queue costs forty reads no matter how much history sits beside it.

Closing is a REMOVE, not a flagwhy

The obvious design puts status = 'CLOSED' on the item and filters the index on it. That index still holds every ticket ever raised, and every read pays to skip them. Removing the index attributes deletes the index entry instead, so a closed ticket stops costing the queue read anything at all. Removal is asynchronous, though - a global index is updated shortly after the base table, not with it - so a just-closed ticket can appear on one more queue read, and an agent picking work has to tolerate being handed something already done.

The queue can be sorted by anything you write into ittrade-off

GSI1SK holds the time the ticket was opened, so the queue comes back oldest first and the agent works the backlog in order. Writing a priority in front of it - P1#<timestamp> - would sort urgent work above old work instead, without changing the base table's key schema. The index sort key is a free choice, and it is where a worklist's policy actually lives. One caveat the shape hides: every open ticket shares GSI1PK = QUEUE#open, so the queue is a single index partition and its write rate is bounded accordingly.

Closing is a design here, not a live demonstrationtrade-off

The preview console runs the queue read, not the close: the resolver templates writes without emitting them as runnable, so there is no button here that closes a ticket and shows it leave the index. The engine itself performs the update; this page cannot drive it.

Taught in the course

support-ticket-queue
Try an example

Every open ticket, oldest first, from an index holding nothing else.

PK(pk)
GSI1PK
GSI1SK
assignee
openedAt
status
subject
TICKET#t-4821
QUEUE#openS
2026-08-13T19:12:00Z#t-4821S
meiS
1786648320N
OPENS
Card declined at checkoutS
TICKET#t-4790
QUEUE#openS
2026-08-12T12:00:00Z#t-4790S
1786536000N
OPENS
Export finishes but the file is emptyS
TICKET#t-4655
QUEUE#openS
2026-08-10T00:00:00Z#t-4655S
rajS
1786320000N
OPENS
Cannot invite a second adminS
TICKET#t-4402
meiS
1785715200N
CLOSEDS
Password reset email never arrivedS
TICKET#t-4310
samS
1785110400N
CLOSEDS
Invoice shows the wrong VAT rateS
TICKET#t-4188
rajS
1784419200N
CLOSEDS
Timezone wrong on scheduled reportsS

Run an operation to see the raw engine response.

table support-ticket-queuekeys PKitems 6

The in-browser engine is a preview build. Transactions, vector search, streams, tags and TTL are among the operations it doesn't implement yet.