> ## Documentation Index
> Fetch the complete documentation index at: https://upstash-fix-issues-on-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating to v2

QStash v2 is almost a complete rewrite of the existing system allowing us to scale horizontally much easier to meet the demand.

As a result of that, a few endpoints have changed and we also added new ones.

* [v1 reference](/qstash/qstash-v1/deprecation)
* [v2 reference](/qstash/api)

During the deprecation phase, you can use both versions but we encourage you to move to v2 as soon as possible.

To migrate to v2, all you need to do is call the new [/v2 endpoints](/qstash/api/messages/create).

In the [console](https://console.upstash.com/qstash) you can toggle between versions to access your logs and messages.

## Major changes

### Creating schedules is its own endpoint

Instead of creating schedules through the `/v2/publish` endpoint, there is a dedicated `/v2/schedules` api now.

### Where are the messages in V2 ?

A big difference on v2 is that we no longer keep the messages to be accessed via [Get Message](/qstash/api/messages/get) to scale better.

* A message is removed from the messages list if the call was successful.
* If the publish is failed, it will be moved to [DLQs](/qstash/features/dlq).
* This endpoint will return a message only if a message is retrying.

A common workflow was to check the message via message id [Get Message](/qstash/api/messages/get) to see if it was successful or not.
This was not a good workflow because, it is not clear when to check this endpoint to take an action.

Instead in v2, to check a message is failed and act on it, you can:

1. Use [Upstash-Failure-Callback](/qstash/features/callbacks#what-is-a-failure-callback). Give the `Upstash-Failure-Callback` when publishing
   the message to be called when the message is failed to be delivered. In the given endpoint:

   * Handle the message.
   * Remove it from DLQ using [Delete a Message From DLQ](/qstash/api/dlq/deleteMessage) via the `dlqId` delivered to [Upstash-Failure-Callback](/qstash/features/callbacks#what-is-a-failure-callback).

2. Use [DLQs](/qstash/features/dlq). This means that you need a continuously running task to read the messages from DLQ.
   The workflow in this case looks like this:

   * Get all the messages with the last known cursor(Cursor will be empty in the beginning)
   * Update the last known cursor with the cursor in the response.
   * If the messages are empty, query the endpoint again after a delay.
   * If there are messages, handle and delete them from DLQ via [Delete a Message From DLQ](/qstash/api/dlq/deleteMessage)
   * Query the endpoint again after a delay with the updated cursor.

With this follow, in a good run, DLQ should be empty. It will have messages only when there is something wrong with your service.
