After migrating from Classic¶
If Tinybird migrated your Workspace for you, it was upgraded in place and kept its name. Your data, Tokens, and Endpoint URLs are unchanged. What changes is how you make changes from now on.
This guide covers what's different in your migrated Workspace and how to work with Forward from this point onwards. For why Forward works this way, see Why migrate to Forward.
What didn't change¶
The migration moved no data and rewrote no URLs. The following survived it untouched:
- Your data. Every Data Source you had, with every row still in it. The migration upgraded the Workspace around your data rather than copying, moving, or reingesting it, so there's nothing to restore or backfill.
- Your Tokens. Same values and same permissions. Nothing to rotate.
- Your Endpoint URLs.
/v0/pipes/<pipe>.jsonanswers as it did before, with the same Query Parameters and the same response formats. - Your ingestion. The Events API and the Data Sources API append operations are unchanged. Producers kept writing during the migration.
- Your Copy Pipes. Still running on the same schedule.
If your app talks to Tinybird over HTTP, it kept working through the migration and you don't need to change anything in it.
What changed¶
Changes go through deployments¶
Your Data Sources, Pipes, and Connections are now described by datafiles: a project you keep in version control and deploy. The Tinybird UI shows you what's running. It's no longer where you change it.
The Classic management endpoints now return a 403:
Adding or modifying data sources to this workspace can only be done via deployments.
You get the same response for Pipes, for Connections, and for the Classic CLI commands that wrapped them. Reading and querying aren't affected.
Your Classic Branches and releases were deleted¶
The migration deletes your Classic Branches and releases. It doesn't carry them over, and you can't recover them. Each has an equivalent in Forward:
- Branches. Forward has its own Cloud Branches, and they're the default way to develop a project. A branch gets its own database, Token namespace, and API surface, and can attach the latest production partition so you develop against real values. Create one with
tb branch create, or runtb buildfrom a Git branch and Tinybird creates a matching Cloud Branch for you. - Releases. Deployments replace them. You prepare each change as a new deployment, check and test it, then promote it. To roll back, promote the previous deployment.
Read and append Token scopes live in your datafiles¶
Your Tokens keep working and keep their values, but the resource scopes DATASOURCES:READ, DATASOURCES:APPEND, and PIPES:READ are now granted by the datafile that defines the resource:
TOKEN "tracker" APPEND
Granting those scopes through the Tokens API returns the same 403 described in Changes go through deployments. Admin Tokens aren't affected, so you can still create and revoke them as before. See Tokens.
The CLI is a different tool¶
tb is now the Tinybird Forward CLI. It runs a complete Tinybird on your machine, builds and tests your project locally before anything reaches Tinybird Cloud, and deploys it when you're ready. Classic CLI commands don't carry over. See Where your old workflow went.
The CLI isn't the only way to work with Forward. See How you work with Forward from here.
Get your project onto your machine¶
Your Workspace runs in Forward, but the datafiles that describe it aren't on your machine yet. This is the one piece of setup the migration couldn't do for you.
Install the Tinybird Forward CLI¶
Run the following command to install the Tinybird Forward CLI and the Tinybird Local container:
curl https://tinybird.co | sh
See Tinybird Local for more information.
Log in to your Workspace¶
tb login --workspace <your-workspace>
A browser window opens to confirm. If your Workspace isn't in the default region, run tb login -i and select your region from the list. See Regions and endpoints.
Pull your project¶
mkdir my-tinybird-project && cd my-tinybird-project
tb --cloud pull
This writes everything your Workspace runs as datafiles, in the layout Forward expects: datasources/, endpoints/, pipes/, materializations/, copies/, and connections/.
For connector-backed projects, the pull writes a .connection file per Connection and stores the credentials as secrets referenced with tb_secret(...). Open each .connection file and confirm the credentials reference and region before you deploy.
The pull writes datafiles only. It doesn't create a tinybird.config.json, and the CLI doesn't need one to build or deploy what you pulled. Add one when you want to set the default development environment or point tb at a specific folder. See Config files.
Commit your project¶
git init && git add . && git commit -m "Tinybird project"
From now on, this repository is the source of truth for your Workspace. Keep it wherever the rest of your code lives.
Check that it builds¶
tb dev
tb dev starts Tinybird Local and rebuilds as you edit, so you can develop against real queries without touching production. tb build runs a single build, and tb test runs your tests.
Make your first change¶
The loop from now on is the same every time, whether you're adding a column or a whole Endpoint:
tb build
tb test
tb --cloud deploy
tb --cloud deploy creates a deployment, checks it against your live Workspace, and promotes it when it's ready.
If a change would drop or rewrite existing data, the deploy stops and tells you. Pass --allow-destructive-operations only when that's what you intend. See Evolve data sources.
How you work with Forward from here¶
Your migrated Workspace is a datafile project: the resources you pulled are .datasource, .pipe, and .connection files, and the Tinybird CLI builds, tests, and deploys them. That's the closest continuation of how you worked in Classic, and this guide assumes it. It isn't the only option:
- Datafiles and the Tinybird CLI. What you have now. Resources live in
.datasource,.pipe, and.connectionfiles, andtbbuilds, tests, and deploys them. See the CLI quickstart. - TypeScript or Python SDK. Define the same resources in code and use a typed client for ingest and queries. You don't rewrite them by hand: the SDKs convert your existing datafiles for you. See Work with the TypeScript or Python SDK.
- MCP. Connect an agent to your live Workspace through the Tinybird MCP server, so it can explore your data and call your published Endpoints. Agent skills teach the agent how to change your project. MCP lets it query what's running. Use a resource-scoped Token to limit what the agent can reach. See MCP.
- Coding agents. Install the Tinybird agent skills so an agent understands your project structure and workflow:
npx skills add tinybirdco/tinybird-agent-skills
See Agent skills.
Work with the TypeScript or Python SDK¶
If you'd rather define your project in TypeScript or Python than in datafiles, each SDK ships its own tinybird CLI that can convert what you already have. The result is the same Workspace and the same deployments, described in code.
Run these steps in the project you pulled in Get your project onto your machine, so the SDK finds your datafiles.
Install the SDK¶
pnpm add @tinybirdco/sdk
Initialize the project¶
npx tinybird init
This creates tinybird.config.json and .env.local for authentication, authenticates you against Tinybird Cloud, and can add CI/CD workflow files.
When it finds your .datasource and .pipe files, it asks what to do with them. Choose Define resources in TypeScript to generate lib/tinybird.ts from your Workspace resources. If you skip, init writes an example lib/tinybird.ts instead. Replace it in the next step rather than deploying it.
Convert the datafiles into code¶
You already have the datafiles from tb --cloud pull, so there's nothing to download. Pass them to migrate, with paths relative to your project root. Run it with --dry-run first to see what it produces:
npx tinybird migrate "**/*.datasource" "**/*.pipe" "**/*.connection" --out lib/tinybird.ts
Skip this step if init already generated lib/tinybird.ts from your Workspace.
Review the generated definitions against your datafiles before you deploy. The SDK deploys only what include in tinybird.config.json lists, so the datafiles you converted are ignored from here on. Remove them once the generated code matches, so the project keeps one definition of each resource.
Develop and deploy¶
npx tinybird dev
npx tinybird deploy --check
npx tinybird deploy
npx tinybird dev watches for changes and syncs them to a Cloud Branch by default. Pass --local to work against Tinybird Local instead, or --branch to name the branch.
tinybird deploy targets your main Workspace, and takes --allow-destructive-operations for the same cases as the CLI.
For the full command list, see the TypeScript SDK CLI and Python SDK CLI references. For the resource definitions themselves, see TypeScript SDK resources and Python SDK resources.
Where to look when something breaks¶
Forward gives you the same logs in the UI and the CLI. To follow an ingestion issue, a job, or a failing Endpoint from your terminal:
tb --cloud logs
By default this reads tinybird.datasources_ops_log, tinybird.pipe_stats_rt, and tinybird.jobs_log for the last hour. Use --source to target others, such as tinybird.endpoint_errors or tinybird.kafka_ops_log, and --start to widen the window.
The Logs page in Tinybird Cloud shows the same events. For longer investigations, query the Service Data Sources directly, starting with the query log for Endpoint and query behavior.
Where your old workflow went¶
| In Classic | In Forward |
|---|---|
| Editing a Pipe or Data Source in the UI | Edit the datafile, then run tb --cloud deploy |
tb push and tb pull | tb --cloud deploy and tb --cloud pull |
POST /v0/datasources and POST /v0/pipes | Datafiles, applied by a deployment |
| Classic Branches | Cloud Branches, created with tb branch create or automatically by tb build |
| Releases | Deployments |
tb auth | tb login |
| Regression and data quality tests | Fixture tests run by tb test. See Test your project |
Troubleshooting¶
403: modifications can only be done via deployments¶
Something is still trying to change resources through the Classic API or the Classic CLI, often a deploy script or a continuous integration job. Point it at a deployment instead, following the steps in Get your project onto your machine. See CI/CD.
The tb migrate-to-forward command is unavailable ¶
Your Workspace is already migrated, so there's nothing left to run:
This command is unavailable for Tinybird Forward workspaces.
A Classic Branch or release is missing¶
The migration deleted them and they can't be recovered. Recreate the Branch as a Cloud Branch from your pulled project:
tb branch create <branch-name> --last-partition
For a release, promote the equivalent deployment instead.
An Endpoint returns a different result than before¶
The migration doesn't change queries or data, so this isn't expected. Contact Tinybird support with your Workspace name before you change anything yourself.