Skip to content

Safer background jobs with VQueue

4 min readValkeyQueuesLayerbase

Your app publishes a receipt job. The request times out. Did the queue accept it, or should you publish again?

That ambiguity is one of the problems addressed by the latest VQueue update. VQueue is the HTTP job queue already included with every Layerbase Valkey database, including the Free plan. It delivers signed requests to your endpoint, retries failed attempts, and lets you inspect and replay failed jobs from the dashboard.

The latest changes add explicit publish deduplication, verified archiving for delivered payloads, and account-level capacity limits. Here is how to use them, and when an included queue could save you a separate bill.

Retry publishing without creating another job

Use the @upstash/qstash client with your VQueue endpoint and a stable deduplicationId:

ts
import { Client } from '@upstash/qstash'

const queue = new Client({
  baseUrl: process.env.VQUEUE_URL!,
  token: process.env.VQUEUE_TOKEN!,
})

const receiptJob = {
  url: 'https://your-app.example.com/api/jobs/send-receipt',
  body: { orderId: 'order-123' },
  deduplicationId: 'receipt-order-123',
  retries: 3,
}

const { messageId } = await queue.publishJSON(receiptJob)

If the publish response is lost, retry the same request with the same ID. Within 24 hours, VQueue returns the original message ID. Changing the request while reusing the ID returns a conflict. IDs are scoped to one database; after the window expires, reusing an ID can create a new job.

This protects publishing. Your receiver still needs to handle duplicate deliveries: a worker can send a request and crash before recording its success. Use the delivery message ID as an idempotency key and make recording it atomic with your application's side effect where possible. For email, use the provider's idempotency mechanism if it has one; a separate database flag alone does not close every crash window.

Verify incoming signatures before processing the raw request body. The setup guide includes the complete receiver configuration for the supported SDK version, @upstash/qstash 2.11.0.

Find a failed job and recover it

Open your Valkey database's Connect > Parameters > VQueue panel. Inspect delivery history, attempt counts, and the last error. Fix the receiver, then replay the selected dead-lettered job. Replay preserves its message ID, so keep the receiver's idempotency behavior in place.

Delivered payloads become eligible for archiving after 24 hours. VQueue verifies the stored copy before clearing the local payload; an unsuccessful archive leaves the original intact. Archived delivered payloads remain available through message lookup and export. Pending and dead-letter payloads do not expire automatically.

Each account has a local allowance across its databases on a server, so creating another database does not bypass the limit. Delivered payloads retained after a database is deleted can also archive under their recorded owner.

Could it cost less than another queue?

The strongest fit is an app already using Layerbase Valkey whose jobs fit VQueue's supported operations and limits. There is no additional queue subscription or per-message VQueue charge. Your Layerbase plan, applicable resource charges, and the cost of running your receiving endpoint still count.

Official prices checked October 7, 2026, in USD:

ServicePublished pricingWhere VQueue fits
Upstash QStashFree: 1,000 messages/day. Pay as you go: $1 per 100,000 messages; each delivery attempt, including retries, counts.The closest comparison for HTTP delivery. An included queue can avoid a paid queue bill, but QStash Free may already cost you nothing.
Google Cloud TasksFirst 1 million billable operations/month free, then $0.40/million up to 5 billion. Operations include API calls and push attempts, chunked at 32 KB.Usually a convenience comparison for a small app, not a meaningful price saving. Its free allowance is substantial.
Trigger.devFree includes $5/month in credits. Hobby is $10/month with $10 in credits; usage includes invocation and compute costs.If all you need is a short request to an existing endpoint, VQueue may avoid a paid task platform. Trigger.dev also runs your code, which VQueue does not.

For QStash, check the supported-operation matrix before migrating. VQueue supports a subset of its client API, not full feature parity. For Trigger.dev, moving execution to your own endpoint changes both the architecture and the compute bill. Neither comparison justifies replacing a service whose additional capabilities you need.

If your workload already fits a competitor's free tier, the case for VQueue is fewer services to configure, not lower queue fees.

Check capacity before comparing bills

VQueue currently allows 64 KiB bodies, scheduling up to seven days ahead, and a 15-second delivery-attempt deadline. It does not provide recurring schedules, named FIFO queues, or a workflow execution engine.

Per account, per server, the limits are 1,000 local payloads and 10,000 retained history records, shared across databases. Archiving frees local payload capacity; it does not remove history. History has no automatic expiry or monthly reset. At the history limit, new publishes stop; contact support if capacity stays full. Shared host limits and disk-pressure guards also apply.

That makes a comparison against millions of monthly deliveries misleading. VQueue's current bounds must fit the workload over time, not just on its first day. It also has no qualified host-loss recovery or failover guarantee; delivered-payload archiving does not establish recovery for every accepted job.

For a small integration already using Valkey, the included queue is worth trying. For sustained volume, long-running execution, or features outside the compatibility guide, choose the service that meets those requirements first and compare the total bill second.

Create a Valkey database, then follow the VQueue setup guide. If you already have Valkey on Layerbase, the connection values are in your dashboard.