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 application 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 as above. 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.
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¶
tb migrate-to-forward writes project_type: "cli" into your tinybird.config.json, so your migrated project defines its resources as datafiles. That's the closest continuation of how you worked in Classic, and everything above 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.
- 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.
Install the SDK¶
pnpm add @tinybirdco/sdk
Initialize the project¶
npx tinybird init
This creates tinybird.config.json, lib/tinybird.ts for your resource and client definitions, and .env.local for authentication. It also authenticates you against Tinybird Cloud and can add CI/CD workflow files.
Pull your Workspace resources¶
npx tinybird pull
This downloads what your Workspace runs as datafiles. If you already ran tb --cloud pull, you can point the next step at those files instead.
Convert the datafiles into code¶
Pass the datafiles you want to convert. Run it with --dry-run first to see what it produces:
npx tinybird migrate "tinybird/**/*.datasource" "tinybird/**/*.pipe" "tinybird/**/*.connection"
Review the generated definitions against your datafiles before you deploy.
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.
tb migrate-to-forward reports that it's 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.