Upload Queues
Upload multiple files with bounded concurrency, item state, cancellation, and aggregate progress.
useConvexUploadQueue coordinates independent file uploads. The default maximum concurrency is three.
const { items, aggregateProgress, enqueueSafe, cancelItem } = useConvexUploadQueue(
api.files.generateUploadUrl,
{
maxConcurrent: 3,
continueOnError: true,
onQueueIdle: (items) => {
console.info('Upload queue settled', items.length)
},
},
)Enqueue files
async function chooseFiles(event: Event) {
const input = event.target as HTMLInputElement
const files = Array.from(input.files ?? [])
const result = await enqueueSafe(files)
if (!result.ok) {
queueError.value = result.error
}
}The queue also accepts per-item forms supported by UploadQueueEnqueueInput when files need different mutation arguments.
Render item state
<template>
<input type="file" multiple @change="chooseFiles" />
<progress :value="aggregateProgress" max="100" />
<ul>
<li v-for="item in items" :key="item.id">
{{ item.file.name }} — {{ item.status }} — {{ item.progress }}%
<button
v-if="item.status === 'queued' || item.status === 'pending'"
@click="cancelItem(item.id)"
>
Cancel
</button>
</li>
</ul>
</template>Queue controls
| Method | Effect |
|---|---|
cancelItem(id) | Cancel one queued or active item |
cancelAll() | Cancel all unfinished items |
clearFinished() | Remove success/error/cancelled rows |
reset() | Cancel unfinished work and clear queue state |
continueOnError: false stops scheduling remaining queued items after the first error and settles those items as cancelled. A later enqueue does not silently resume the stopped batch.
Lifetime
The queue is component/app memory. It is not persistent background work. Navigating away disposes active uploads. Use server-side job records for durable processing after upload.