Last update: 2025-09-12T09:36:10.000Z
Content:
---
title: "Table functions · Tinybird Docs"
theme-color: "#171612"
description: "Ingest data from remote databases into Tinybird."
inkeep:version: "forward"
---




# Table functions [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#table-functions)

Copy as MD Tinybird table functions allow you to read data from an existing database and schedule a regular copy pipe to orchestrate synchronization. You can load full tables or incrementally sync your data.

Tinybird supports the following table functions:

- [  Apache Iceberg](/docs/forward/get-data-in/table-functions/iceberg)
- [  MySQL](/docs/forward/get-data-in/table-functions/mysql)
- [  PostgreSQL](/docs/forward/get-data-in/table-functions/postgresql)
- [  URL](/docs/forward/get-data-in/table-functions/url)

## Prerequisites [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#prerequisites)

Your database needs to be open and public, exposed to the internet with publicly signed certs, so you can connect to it by passing the hostname, port, username, and password.

### Environment Variables API [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#environment-variables-api)

The Environment Variables API is currently only accessible at API level.

Pasting your credentials into a pipe node or datafile as plain text is a security risk. Instead, use the Environment Variables API to [create two new secrets](/docs/api-reference/environment-variables-api#post-v0secrets) for your username and password.

In the next step, you can interpolate your new secrets using the `tb_secret` function:

{{tb_secret('db_username')}}
{{tb_secret('db_password')}}
## Load an external table [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#load-an-external-table)

Create a new pipe node. Call the table function in the `FROM` and pass the connection details:

##### PostgreSQL table function example

SELECT *
FROM postgresql(
  'aws-0-eu-central-1.TODO.com:3866',
  'postgres',
  'orders',
  {{tb_secret('db_username')}},
  {{tb_secret('db_password')}},
) Publish this node as a copy pipe, thereby running the query manually. You can choose to append only new data, or replace all data.

### Using datafiles [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#using-datafiles)

You can also define node logic in [Pipe files](../dev-reference/datafiles/pipe-files) . An example for a PostgreSQL eCommerce `orders_backfill` scenario, with a node called `all_orders` , would be:

NODE all_orders
SQL >

    %
    SELECT *
    FROM postgresql(
      'aws-0-eu-central-1.TODO.com:3866',
      'postgres',
      'orders',
      {{tb_secret('db_username')}},
      {{tb_secret('db_password')}},
    )

TYPE copy
TARGET_DATASOURCE orders
COPY_SCHEDULE @on-demand
COPY_MODE replace
## Include filters [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#include-filters)

You can use a source column to filter by a value in Tinybird, for example:

##### Example copy pipe with PostgreSQL table function and filters

SELECT *
FROM postgresql(
  'aws-0-eu-central-1.TODO.com:3866',
  'postgres',
  'orders',
  {{tb_secret('db_username')}},
  {{tb_secret('db_password')}},
  )
WHERE orderDate > (select max(orderDate) from orders)
## Schedule runs [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#schedule-runs)

When publishing as a copy pipe, most users set it to run at a frequent interval using a cron expression.

You can also trigger the copy pipe on demand:

curl -H "Authorization: Bearer <PIPE:READ token>" \
    -X POST "https:/tinybird.co/v0/pipes/<pipe_id>/run" Having on-demand pipes in your workspace is helpful, as you can run a full sync manually any time you need it. You might also use them for weekly full syncs.

## Synchronization strategies [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#synchronization-strategies)

When copying data from your database to Tinybird, you can use one of the following strategies:

- Use `COPY_MODE replace`   to synchronize small dimensions tables, up to a few million rows, in a frequent schedule (1 to 5 minutes).
- Use `COPY_MODE append`   to do incremental appends. For example, you can append events data tagged with a timestamp. Combine it with `COPY_SCHEDULE`   and filters in the copy pipe SQL to sync the new events.

### Timeouts [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#timeouts)

When synchronizing dimensions tables with `COPY_MODE replace` and 1 minute schedule, the copy job might time out because it can't ingest the whole table in the defined schedule.

Timeouts depend on several factors:

- The timeout configured in your external database.
- The external database load.
- Network connectivity, for example when copying data from different cloud regions.

Follow these tips to avoid timeouts using incremental appends:

- Make sure to tag your data with an updated timestamp and use the column to filter the copy pipe SQL.
- Configure the copy pipe with an incremental append strategy and 1 minute schedule. That way you make sure only new records in the last minute are ingested, thus optimizing the copy job duration.
- Create an index in the external table to speed up filtering.
- Create the target data source as a ReplacingMergeTree using a unique or primary key as the `ENGINE_SORTING_KEY`   . Rows with the same `ENGINE_SORTING_KEY`   are deduplicated. Remember to use the `FINAL`   keyword when querying the data source to force deduplication at query time.
- Combine this approach with an hourly or daily replacement to get rid of deleted rows.

## Observability [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#observability)

Job executions are logged in the `datasources_ops_log` [Service Data Source](../monitoring/service-datasources) . You can check this log directly in the Data Source view page in the UI. Filter by `datasource_id` to monitor ingestion through the table functions from the `datasources_ops_log`:

##### Example query to the datasources_ops_log Service data source

SELECT
  timestamp,
  event_type,
  result,
  error,
  job_id
FROM
  tinybird.datasources_ops_log
WHERE
  datasource_id = 't_1234'
AND
  event_type = 'copy'
ORDER BY timestamp DESC
## Limits [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#limits)

The table functions inherit all the [limits of copy pipes](../pricing/limits#copy-pipe-limits).

Environment Variables are created at a workspace level, so you can connect one of each external database per Tinybird workspace.



Check the [limits page](/docs/forward/pricing/limits) for limits on ingestion, queries, API Endpoints, and more.

## Billing [¶](https://www.tinybird.co/docs/forward/get-data-in/table-functions#billing)

There are no additional or specific costs for the table function itself; only the costs associated with copy pipes apply. For more information on data operations and their charges, see the [billing docs](../pricing/billing).


