What Are the Top ETL Tools in 2026? (Tested & Compared)

Table of ContentsToggle Table of Content

Summary

  • Skyvia: A no-code, cloud-native platform featuring visual mapping, predictable tiered pricing, and built-in tools for end-to-end ELT, dbt integration, and Reverse ETL.
  • Fivetran: Fully managed enterprise ingest platform utilizing log-based CDC and automated schema drift handling, backed by a usage-based MAR pricing model.
  • Airbyte: Highly customizable, open-source integration framework that gives developer-led teams absolute control over deployment, connectors, and infrastructure.
  • Matillion: A specialized enterprise tool built for data engineers to execute heavy, push-down SQL and Python transformations directly inside cloud data warehouses.
  • Estuary Flow: A high-throughput streaming platform providing sub-second, low-latency Change Data Capture (CDC) for real-time operational analytics.

Has your pipeline said “Success,” and when you check your reports, the numbers aren’t right? How about quiet pipeline failures? Or maybe
pricing models that jump 40–70% after adding a few core SaaS connectors? If it’s a ‘Yes’ in any or all of them, it’s time to look for the top ETL tools in 2026.

But let me be honest. We are the team behind Skyvia. We built a no-code cloud data integration platform, so we naturally believe in our product. However, Skyvia is not a magic wand for every data stack. Requirements, use cases, and even budgets may differ with every company. There’s no one tool for everything. That’s why we will test Skyvia alongside market leaders using real test data.

But before we dive into the tests, let me show how we did it.

How Did We Test and Evaluate These Data Integration Tools?

We did our test using real test data in HubSpot and PostgreSQL hosted in Neon. Meanwhile, Snowflake and BigQuery were selected as representative cloud data warehouse targets.

The ETL tools we picked are the following:

  • Skyvia
  • Fivetran
  • Airbyte
  • Matillion, and
  • Estuary

Of the 5 ETL tools, Fivetran, Estuary, and Airbyte’s PostgreSQL connector require the following:

  • The database wal_level set to logical.
  • A Publication
  • A Replication Slot
  • and the tables included for replication

Neon accepts these configurations, and so it was chosen as the PostgreSQL host.

We’re going to have the same data and test cases to use. This way you will see how different ETL tools handle connections, organize pipeline creation, and structure data in the chosen targets. You will also know how easy (or difficult) pipeline creation is in each respective ETL tool.

Test Lab Overview

Let me show you our test data first.

For HubSpot

I used a free HubSpot account with 999 Contacts. The limit is actually 1000 contacts, but HubSpot didn’t allow me last time to add the 1000th row. Note that the names and email addresses are fictitious and generated for testing only.

a free HubSpot account with 999 Contacts

For PostgreSQL

Below are the tables we will replicate:

PostgreSQL table sample

The customer is in HubSpot, and the transactions are in PostgreSQL.

We have 500 products, as seen in the page counter:

Postgres test table products

Then, 1797 orders:

Postgres test table orders

And 3603 order items:

Postgres test table order items

I have to set the 3 tables for replication by doing this:

ALTER TABLE products REPLICA IDENTITY DEFAULT;
ALTER TABLE orders REPLICA IDENTITY DEFAULT;
ALTER TABLE order_items REPLICA IDENTITY DEFAULT;

When you do the same to your tables, make sure you’re pointing to the intended database. Or the ETL tools will either not find it or will give you an error.

The test aims to replicate the rows into a Snowflake database with different schemas. Each tool will have its own schema instead of overwriting each other’s copy of the tables. That way, we will see what the result will look like for each of the ETL tools.

Intended Warehouse Output

Snowflake target warehouse output

Now, this won’t mean that the ETL tools can write to them right away. You need to set permissions. Here’s what I did for the Snowflake warehouse, database, and schemas:

GRANT USAGE ON WAREHOUSE COMPUTE_WH TO ROLE PUBLIC;
GRANT USAGE ON DATABASE SALES_WAREHOUSE TO ROLE PUBLIC;
GRANT USAGE ON SCHEMA SALES_WAREHOUSE.SKYVIA TO ROLE PUBLIC;
GRANT USAGE ON SCHEMA SALES_WAREHOUSE.AIRBYTE TO ROLE PUBLIC;
GRANT USAGE ON SCHEMA SALES_WAREHOUSE.FIVETRAN TO ROLE PUBLIC;
GRANT USAGE ON SCHEMA SALES_WAREHOUSE.MATILLION TO ROLE PUBLIC;
GRANT USAGE ON SCHEMA SALES_WAREHOUSE.ESTUARY TO ROLE PUBLIC;

GRANT CREATE TABLE ON SCHEMA SALES_WAREHOUSE.SKYVIA TO ROLE PUBLIC;
GRANT CREATE TABLE ON SCHEMA SALES_WAREHOUSE.AIRBYTE TO ROLE PUBLIC;
GRANT CREATE TABLE ON SCHEMA SALES_WAREHOUSE.FIVETRAN TO ROLE PUBLIC;
GRANT CREATE TABLE ON SCHEMA SALES_WAREHOUSE.MATILLION TO ROLE PUBLIC;
GRANT CREATE TABLE ON SCHEMA SALES_WAREHOUSE.ESTUARY TO ROLE PUBLIC;

GRANT SELECT ON FUTURE TABLES IN DATABASE SALES_WAREHOUSE TO ROLE PUBLIC;
GRANT INSERT ON FUTURE TABLES IN DATABASE SALES_WAREHOUSE TO ROLE PUBLIC;
GRANT UPDATE ON FUTURE TABLES IN DATABASE SALES_WAREHOUSE TO ROLE PUBLIC;
GRANT DELETE ON FUTURE TABLES IN DATABASE SALES_WAREHOUSE TO ROLE PUBLIC;

GRANT CREATE SCHEMA ON DATABASE SALES_WAREHOUSE TO ROLE PUBLIC;

I just used the PUBLIC role for simplicity and testing purposes. But you need to set aside a separate role in your Snowflake production database. We are setting these up too because Snowflake won’t allow a user with administrative privileges when connecting from the ETL tools. For this case, I used a TESTUSER account with the PUBLIC role, which aligns with the permissions above.

You also need to configure a private key for the Snowflake account you will use. For my TESTUSER, I followed the instructions here for key-pair authentication. This is very important because Snowflake will no longer accept a userid/password authentication. This applies to all the ETL tools connecting to Snowflake.

The same principle applies in BigQuery. Each tool will target a different dataset.

BigQuery target warehouse output

We will find out if the tool will write to the intended schema or dataset, or if it will decide on its own.

That said, we committed 40 hours to test the ETL tools.

Why Two Targets?

The two targets are used as evaluation targets, not because a production system necessarily needs both. We are also not recommending which data warehouse is best for your needs.

Many organizations will use one data warehousing platform. It will be very rare to use two. So, treat these tests not as an architectural recommendation, but for testing and evaluation.

The Four Technical Benchmarks

Though you will see how the setup for each tool is done, we would like to know the following:

  • Time-to-First-Sync: How long did it take the tool to replicate the HubSpot contacts and Postgres tables to Snowflake and BigQuery? We’re hoping each tool will have some form of reports on how long the replication took place.
  • Schema Evolution Resilience: When the source schema adds or removes a column, do you need to change the pipeline, or is it automatic? In our test, we will add a column in the products table in PostgreSQL.
  • Pipeline Visibility & Failure Recovery: We are going to examine logs, error handling, notifications, and stuff that will let you know if the pipeline run is a success or not.
  • Pricing Predictability: How will the ETL tools let you know how much you will pay? Is the pricing plan straightforward? Would you know how much you will pay given a workload like next month or by the end of the year?

These same criteria will be used across all candidate ETL tools.

Testing Limitations

You might have noticed that we will use relatively small datasets. Let me tell you that the sources, destinations, and the pipelines were created using free tiers and trial accounts, which impose limitations on data volume and usage. For example, the HubSpot test environment limits the sample to 1,000 contacts.

With these limitations, we can’t test using large datasets. We also would like to make the tests uniform across the different ETL tools.

The purpose of these tests is therefore to evaluate the practical experience of configuring and running each ETL tool rather than to benchmark enterprise-scale performance or a feature claimed by the makers of the tool. Claims about pushdown transformation, large-volume processing, scalability, and production performance are based on the capabilities and architecture offered by each platform and should not be interpreted as results from the test.

What Key Criteria Should You Use to Evaluate ETL & ELT Platforms?

We already stated earlier what we will watch for in the test. But what are the things you’re going to live with after purchasing the tool?

The right one is more than just counting connectors. Let’s discuss 4 of these criteria.

Ingestion & Pipeline Architecture

Start by knowing how data will move from source to destination and where data transformation will happen. You have 3 scenarios:

  • ELT (Extract, Load, Transform): Modern data stacks favor this one, where you load data to the data warehouse and do the transformation from there using its compute engine.
  • ETL (Extract, Transform, Load): Where you want it cleaned first through transformation before loading to the data warehouse.
  • Reverse ETL: It’s reverse because the data warehouse becomes the source and the target is the operational systems. For example, a company might calculate customer scores or lifetime value in its warehouse and then write those metrics back to Salesforce, HubSpot, or Zendesk for sales and customer-service teams to use.

Do you need all 3? If it’s a ‘Yes’, is having separate tools for each a better solution or a tool that does it all?

The key question is not whether a platform calls itself ETL or ELT. It’s where the transformation happens and whether that architecture fits your workload.

Sync Frequency & Latency Mechanics

How quickly does your data need to move from the source to the destination? Your daily report has very different requirements from an application that needs data within seconds. There are a few common approaches:

  • Scheduled polling: The platform queries the source at set intervals like every minute, every hour, or once a day. It works when near real-time data is not needed.
  • Log-based Change Data Capture (CDC): The tool reads database transaction logs to identify inserts, updates, and deletes. This captures changes with less overhead, and it’s very useful for high-volume databases.
  • Continuous streaming: Changes are processed continuously, often with very low latency. This is useful for operational analytics, real-time dashboards, and other workloads where a scheduled sync is not acceptable.

Don’t just check the tool’s shortest advertised sync interval. Check the tool’s latency and how the source system can handle the resulting workload.

Schema Drift Automation

Databases and APIs change as business requirements evolve. Because of that, tables change or new ones are added. New, changed, or deleted columns can be a pipeline headache. That’s schema drift, and a perfectly working pipeline yesterday may break tomorrow because of these changes.

Unless the ETL tool handles it automatically for you. Otherwise, you have to manually change the pipeline too, test it, and deploy it.

Good schema-drift handling can save significant maintenance effort, particularly when integrating SaaS applications whose APIs can change independently of your data team.

Is Automatic Schema Drift Handling Always Ideal?

  • What if the change contains sensitive information? Highly controlled environments may prefer approval first before it goes to the warehouse.
  • What if a change in column type (like DECIMAL to VARCHAR) is a bug in the source system? That shouldn’t go to the warehouse. It’s potentially dangerous.
  • What if an additional column is not needed in the warehouse? It will just be an additional overhead. This applies when the table initially contains 5 columns, but now it’s 10. Should all 10 go to the warehouse?
  • If the source contains JSON columns and you choose to retain them in the warehouse, the physical structure remains, but the logical structure is changed. That will quietly go to the warehouse. If your business requirements need approval, the ETL tool’s physical schema-drift handling will no longer be responsible. You need transformations to exclude the additional JSON property if the logical change is rejected to go to the warehouse.

This only means that good schema-drift handling should give you control over how changes are applied.

Pricing Predictability & Licensing

Know what will actually cause your bill to balloon as your data grows. It’s not commonly advertised on the pricing page.

Here are some common pricing models:

  • Volume-based pricing: This is more predictable. You only pay for the rows processed regardless of the number of connectors used.
  • MAR (Monthly Active Rows) or similar usage metrics: Charges are based on rows affected during a billing period. Historical reloads or re-syncs and frequent updates may significantly add costs.
  • Per connector pricing: Cost will increase as you add more sources and destinations.
  • License plus compute: The ETL platform charges for its service, while transformations pushed down to a cloud warehouse also consume warehouse compute. The ETL subscription is therefore only part of the total cost.
  • Annual contracts: This has a fixed annual cost where you commit to use the tool. Depending on the tool, you may have discounts.

How Do the Top ETL Tools Compare Side-by-Side?

See the best ETL tools for 2026 at a glance below:

Feature / MetricSkyviaFivetranAirbyteMatillionEstuary Flow
Primary Workflow FitNo-Code Cloud Data Integration & End-to-End DWHEnterprise Managed Ingestion & Automated ELTOpen-Source / Developer Infra ControlEngineering Push-Down TransformationReal-Time Streaming & Log CDC
Pricing ModelVolume-based (Records moved); Unlimited usersUsage-based (MAR) + Per-connector pricingPyAirbyte/Airbyte OSS: Free open-source engine + Infra/DevOps costs
Airbyte Cloud: Pay As You Go
Usage-based Matillion CreditsUsage-based (GB moved + tasks)
Minimum Sync Interval1 Minute5 Minutes (1 min on high-tier)1 Hour (Cloud free) / Custom (Self-hosted)1 MinuteSub-second / Continuous streaming
Setup ComplexityVisual / No-Code (Minutes)Low / Configuration-onlyDepending on the offering, it can be Low or High (Requires Docker/Python coding)Medium-High (Requires SQL/Python skills)Medium (CLI + UI)
dbt Transformation SupportYes (Hosted dbt Core inside Skyvia)Yes (dbt Core / dbt Cloud)Yes (External orchestrator required)Native visual dbt & SQL modelingExternal orchestrator required
Reverse ETL Included?Yes (Built-in to operational SaaS apps)Yes (Fivetran Activations)Yes, for supported connectorsAdd-on requiredStream-based activation endpoints
Live Data Access (No Copy)Yes (Skyvia Connect OData/SQL)NoNoNoNo

Which ETL Tool Fits Your Specific Use Case?

This is probably the section you wish to dive into to see which one will fit your use case. The tests won’t reveal a winner. This is not a contest. Just the output of the tests and which areas and use cases the tool will shine.

Let’s begin.

Why Is Skyvia Best for Lean Data Teams, Solo Analysts & No-Code Simplicity?

Skyvia is a no-code data integration platform, and ease of use is at the core of the design. The user interface is clean, and forms are straightforward. You will find connector configurations reusable, so the same configurations need not be typed more than once. Most pipelines can be designed using wizards and simple forms, but features like the Data Flow and Control Flow use drag-and-drop.

I’ve used it many times. I already lost count. I’ve used the easiest feature to move data from HubSpot and PostgreSQL to Snowflake and BigQuery: Skyvia Replication. Before we dive into the tests, let me tell you more about Skyvia and who this is for.

Best for

It’s for everyone who needs systems talking to each other without code. Ideal for solo data analysts, BI leads, IT managers, and RevOps who need reliable pipelines without waiting for IT staff.

Engineers can have their to-do lists crossed out quickly and focus more on other stuff that matters. That means more rollouts and less debugging.

Rating

How do users see Skyvia? Check out reviews from:

  • G2 – 4.8/5 based on 322 reviews
    From G2: “Users consistently praise the ease of use and reliable automation of Skyvia…”
  • Capterra – 4.8/5 based on 116 reviews. 

Pricing Deep Dive

Skyvia is volume-based. That means no surprises on your budget. Skyvia pricing includes Free, Basic, Standard, Professional, and Enterprise, and includes free trials for the paid tiers. Pricing starts at $79/month for Basic.

I used a trial account (which can be your choice too when you start). Below is my usage for this test:

Skyvia overall usage

If those numbers are consistent monthly, I won’t be eligible for the Free tier. The Basic tier will be more applicable. That’s how predictable it is. At $79/month, my annual cost will be $948.

I also have a free tier account, but I can’t use it here because of the higher number of rows. I’ve reached my limit too, and I’m waiting for it to reset the following month.

For more pricing info, visit the Skyvia pricing page.

What Does Building a Data Pipeline Look Like in Skyvia?

The Skyvia replication requires a source and a destination, and we have 2 sources and 2 destinations. You will follow a wizard to create a Skyvia replication. You also need to configure the targets before creating their connections. This means:

  • The Snowflake database and schema should already exist.
  • The BigQuery project, dataset, and cloud storage bucket are configured with the correct permissions.

Pipeline Setup Difficulty: 1/5 (No-Code Visual Wizard)
Time to Launch: 5–10 minutes.

Workflow Steps
  1. Create a Skyvia Connection for the 4 sources (HubSpot, PostgreSQL, Snowflake, and BigQuery)
  2. Add a new Skyvia Replication following a wizard.
    • Create a replication for HubSpot to Snowflake.
    • Do the same to replicate PostgreSQL to Snowflake.
    • Reuse the HubSpot connection and create a replication going to BigQuery.
    • Reuse the PostgreSQL connection and create a replication going to BigQuery.
  3. Run the 4 pipelines to test.
  4. Create a schedule to run the 4 pipelines on demand.

Below is the Skyvia Replication wizard that I used when creating the replication:

Skyvia Replication Wizard

At this point, the HubSpot and BigQuery connections are chosen as source and target. The wizard is now asking what HubSpot objects to replicate.

The other 3 replications use the same wizard.

Connector Configurations

Check out how Skyvia connector configuration looks like for HubSpot, PostgreSQL, Snowflake, and BigQuery.

HubSpot

See what it looks like to configure a HubSpot connection in Skyvia.

HubSpot connection in Skyvia

We don’t need to give Skyvia our HubSpot account and password. What I did was sign in to HubSpot, and HubSpot provided the access token to Skyvia.

PostgreSQL

Then, we have the PostgreSQL connection below:

PostgreSQL connection in Skyvia

Ask your database administrator to provide those credentials for your own connection. Connecting to Neon needs SSL=require, so I set that too. Note that I got a successful connection after I changed the SSL TLS Protocol from 1.1 to 1.2.

Snowflake

Below is my Snowflake connection:

Snowflake connection in Skyvia

I chose Key-Pair authentication because Snowflake won’t accept username/password authentication.

BigQuery

Finally, the following is the BigQuery connection:

BigQuery connection in Skyvia

I signed in to Google for the access token. Then, I provided the BigQuery project ID, dataset, and Cloud Storage Bucket. This needs to be setup in advance before creating the BigQuery connection in Skyvia.

Replication Setup

For the HubSpot to Snowflake replication, below is the final setup after following the wizard.

HubSpot to Snowflake replication in Skyvia

And below is the setup for PostgreSQL to Snowflake replication. The 3 candidate tables (products, orders, and order_items) are indicated.

PostgreSQL to Snowflake replication in Skyvia

I also set the table to be automatically created in Snowflake.

Below is the HubSpot to BigQuery replication. The only thing that changed is the target.

HubSpot to BigQuery replication in Skyvia

Finally, the PostgreSQL to BigQuery replication:

PostgreSQL to BigQuery replication in Skyvia

Since I did this kind of replication setup many times, 2 sources for 2 targets took 10 minutes.

Runtime Results

The initial sync for HubSpot Contacts to Snowflake took 22 seconds, and the 999 contacts are the same as the number from HubSpot earlier.

sync for HubSpot Contacts to Snowflake took 22 seconds

Meanwhile, the 3 tables from PostgreSQL took 32 seconds, and the row counts below are consistent with the source earlier.

3 tables from PostgreSQL took 32 seconds

Let’s check the pipelines going to BigQuery. HubSpot contacts took 22 seconds too, and it successfully replicated 999 rows.

HubSpot to BigQuery contacts took 22 seconds

For PostgreSQL to BigQuery, it took 1 minute and 8 seconds for the initial sync. Below shows the same row counts as earlier.

PostgreSQL to BigQuery, it took 1 minute and 8 seconds

Then, I need to check for schema drift resilience. So, using dbForge Studio for PostgreSQL, I added the sku column to the product table. And then, I did this:

UPDATE products
SET sku = CONCAT(cast(category AS VARCHAR(20)),cast(product_id AS VARCHAR(20))),
         modified=now();

That’s our schema drift. So, how will Skyvia deal with it? I re-ran the PostgreSQL-to-Snowflake pipeline, but I got zero successful rows. It means nothing was replicated to Snowflake. I checked the pipeline. It can detect the new sku column, but it’s excluded in the process.

See below:

Skyvia task editor data schema

I have to mark it as checked and save the pipeline changes. When I save, I get a prompt:

Skyvia task editor data schema modified

It means that I have to choose whether I want a full refresh or not on the next run. I chose to do the full replication again and reset the LastSyncTime. When I re-ran the pipeline, the new column is there in Snowflake.

Skyvia uses a metadata cache to optimize performance. That means the initial columns are stored in a cache so they won’t be read again from the source. That cache needs to reset, or the new column won’t replicate. And it has to be preconfigured that way from the beginning.

Results in Snowflake

Did the data really replicate? One way to find out is to check it in the target.

Skyvia followed the schema target we set in the pipeline. That is, it writes tables under the SKYVIA schema. Columns are flattened as in the source. This means Skyvia prioritized query convenience for us. No need to use functions to flatten the columns in Snowflake. However, Skyvia prefixed the source schema into the table name, so public.products in PostgreSQL becomes public_products in Snowflake.

Here’s the data preview of the HubSpot contacts. Row counts are reported as 999 from the top of the page.

Results in Snowflake: data preview of the HubSpot contacts

Same thing with 500 products from PostgreSQL. Here’s a preview including the additional column added.

Results in Snowflake: data preview of the PostgreSQL products

The orders table shows a rounded-off row count: 1.8K. But that’s close to our 1797 orders.

Results in Snowflake: data preview of the PostgreSQL orders

The same with the order_items table. A rounded-off figure is 3.6K, which is close to our 3603 order items. Since we set up the replication to add the _skyvia_sync timestamp column, it appears below and in the other tables.

Results in Snowflake: data preview of the PostgreSQL order items
Results in BigQuery

The results in BigQuery are generally the same as in Snowflake. The table columns are flattened for query convenience. The tables were loaded into our intended dataset too.

Below are the 999 HubSpot contacts in the skyvia_sales_warehouse dataset:

The results in BigQuery: the 999 HubSpot contacts

Same thing with the products table.

The results in BigQuery: products data

And the orders table:

The results in BigQuery: orders data

Finally, the order_items table:

The results in BigQuery: order items data

That concludes our tests for Skyvia. You now have an idea of the replication setup, initial sync, and target outputs.

The Pros and Cons below are based on the product features, not from the tests.

Pros

  • End-to-End Pipeline in One Tool: Move data in ETL or ELT, model warehouse-side (hosted dbt Core or native SQL), move back to CRMs or OLTP systems (Reverse ETL), and orchestrate execution order with Control Flow.
  • Predictable Volume Pricing: A preset number of rows monthly means you stay on budget every month. Just ensure you have enough rows available per month for uninterrupted pipelines. Includes unlimited users on every plan and a genuine freemium tier (no credit card required).
  • Broader Data Integration Scope: Beyond data warehousing, Skyvia provides 1-way and 2-way data sync, data loading, and live real-time data access via Skyvia Connect (OData/SQL endpoints).

Cons

  • Minimum Sync Interval: Lowest sync interval is 1 minute (polling-based); not designed for sub-second streaming workloads.
  • CDC Scope: Log-based CDC is available for MS SQL Server; other database sources use scheduled incremental polling.
  • Legacy ERP Modules: Skyvia supports Oracle, Dynamics, and NetSuite, but lacks out-of-the-box deep schema adapters for legacy customized SAP environments.
  • Push-Down Engineering: Does not run customized Python/Spark push-down code directly inside Snowflake; heavy developer-only push-down workflows fit platforms like Matillion better.
Ready to Simplify Data Workflows

Why Choose Fivetran for Enterprise-Scale Managed Ingestion?

In our Fivetran test, automatic schema drift handling was flawless. There’s no need for manual intervention. Fivetran is also known for efficient big data processing.

I already tried Fivetran a few times in a similar test. Note that we can’t test the big data processing part, but we can test the schema drift handling.

Best for

Big data companies that prioritize fast scaling, broad connectivity options, and hassle-free schema management will find Fivetran attractive. It’s mostly at home with mid-market and enterprise environments.

If you also don’t mind spikes in monthly payments because of a sudden increase in data volume, this is for you.

Rating

So, how does Fivetran fare? What do users say?

  • G2 – 4.3/5 based on 828 reviews
    From G2: “Users consistently praise the product for its ease of use and reliable data syncing..However, many users express concerns about the high pricing as data volume increases.”
  • Capterra – 4.4/5 based on 25 reviews.   

Pricing Deep Dive

Fivetran is pay-as-you-go, but there’s a Free tier. Paid tiers include Standard, Enterprise, and Business Critical. There’s a pricing calculator where you can compute your possible Monthly Active Rows (MAR). According to Fivetran, MAR is “the number of distinct primary keys synced from the source system to your destination in a given calendar month.”

Fivetran also offers annual Contract pricing and starts at $12,000, as seen below:

Fivetran purchase contract

Since I used a trial account, no billing is computed. But Fivetran recommended the Enterprise plan for me based on the tests I did. See below:

Fivetran billing

Enterprise was chosen because of the cloud provider used in the trial. But actually, the test will fit the Free plan with GCP as the cloud provider.

Fivetran has no posted price for their plans. For more information, visit the Fivetran pricing page.

What Does Building a Data Pipeline Look Like in Fivetran?

In Fivetran, you need to set up connections and destinations. Connections in Fivetran mean the setup of the source data with its intended destination.

Pipeline Setup Difficulty: 2/5 (Configuration-driven).
Time to Launch: 15–30 minutes.

Workflow Steps

Here’s what I did:

  1. Create destinations
    • For Snowflake
    • For BigQuery
  2. Create connections
    • Create a connection for HubSpot with Snowflake as the target.
    • Make a connection for PostgreSQL with Snowflake as the target.
    • Add another connection for HubSpot with BigQuery as the target. I needed to sign in to HubSpot again.
    • Finally, add the last connection for PostgreSQL with BigQuery as the target. I retyped the PostgreSQL config for this connection.
  3. Run the pipelines to test.

Though there is also a wizard, the way the pipeline is organized will let you repeat configuring the sources. This is expected since you don’t normally have 2 data warehouses in a company.

Connector Configurations

I’ll show you Fivetran connector configurations individually.

HubSpot

Similar to Skyvia, I just signed in to HubSpot for authorization. Note the Destination schema. You can’t edit it once you’ve saved it. When I got it wrong, I had to delete the connection and start again. It happened in this test because that same destination schema will be used as the schema in Snowflake.

HubSpot connection in Fivetran
PostgreSQL

Below is the PostgreSQL config. It’s a wizard with green check marks when you’re done. And there’s the destination schema again. But Fivetran doesn’t allow the same destination schema name. So, I used ‘fivetran2’. Sadly, I have no choice, and Fivetran will create a new schema in Snowflake.

The next part of the wizard is for the database host and port.

PostgreSQL connection in Fivetran

Then, the next page of the wizard has the usual credentials: database, username, password. The next part is very important. It assumes we already set wal_level = logical, the replication slot, and the publication name. Fivetran and Neon have good documentation for that.

PostgreSQL connection in Fivetran
Snowflake

Next is the Snowflake destination. I have the private key file prepared for the Private Key box since I used the same one in Skyvia. The other stuff is the usual parameters we need to provide.

Snowflake connection in Fivetran
BigQuery

Finally, we’ll see the BigQuery destination config. It uses a defined Service Account prepared by Fivetran. What I did was give this Service Account permission to my BigQuery project so it can write to datasets.

I didn’t have to show the same HubSpot and PostgreSQL config with BigQuery targets because the target is the only difference. However, the same thing happens. I have to set 2 new schema targets that point to 2 BigQuery datasets. Again, not our original intention.

BigQuery connection in Fivetran
Including Tables in the Pipeline in Fivetran

For the fivetran connection, I marked the HubSpot contacts to include them in the replication. The default is all HubSpot objects.

Including Tables in the Pipeline in Fivetran

For the PostgreSQL to Snowflake replication (fivetran2), I also set the tables to replicate. Note that only the tables you include for publication in the PostgreSQL database will be replicated. You can see below that Fivetran marks the other tables as Table off because they’re not included in the publication. If your table is marked that way but you want it replicated, you need to go back to PostgreSQL to include it in the publication.

Also, there’s a Schema change settings, as you can see below. The default is Allow all new data, which means all new and changed tables and columns will be replicated. If your company requires approval prior to schema change, set this to Block all new data.

Schema change settings in Fivetran

Similarly, I also did the same for HubSpot source and BigQuery destination:

HubSpot source and BigQuery destination in Fivetran

And finally, in PostgreSQL to BigQuery:

PostgreSQL source and BigQuery destination in Fivetran
Runtime Results

Fivetran separates the runtime duration into ExtractProcess, and Load. Each has its own timestamps and duration. Overall, the initial sync of HubSpot Contacts to Snowflake took 49 seconds. It’s the same row count as in the HubSpot source earlier.

the initial sync of HubSpot Contacts to Snowflake took 49 seconds

Below is the PostgreSQL-to-Snowflake initial sync that took 20 seconds. Row counts are consistent with the source.

PostgreSQL-to-Snowflake initial sync that took 20 seconds

Now, we test for schema drift handling. I added the sku column in the products table in PostgreSQL and put some values into it. I didn’t change the pipeline. Then, I re-ran the pipeline. From the screen capture below, only the products table was replicated, which is correct, because that’s the only table that changed. Will the new column be reflected in Snowflake? We’ll find out in a while.

schema drift handling in Fivetran

Next, I moved on to HubSpot to BigQuery replication, and I have a runtime error:

runtime error in Fivetran

From the looks of it, I can tell that it’s a permission problem. I went back to the Google Cloud console. Then, I accessed IAM & Admin -> Service Accounts -> Permissions to give a BigQuery Data Owner permission to create tables.

After that, it’s good. See below:

HubSpot to BigQuery replication historical sync in Fivetran

PostgreSQL to BigQuery did well too. See the following stats below:

PostgreSQL to BigQuery replication historical sync in Fivetran
Results in Snowflake

Are there really rows in Snowflake that Fivetran processed?

Below is the replicated HubSpot contacts. Fivetran also flattened the JSON columns in HubSpot for query convenience.

Results in Snowflake: HubSpot contacts data
Fivetran loaded HubSpot contacts in our intended schema (FIVETRAN). But the PostgreSQL tables were not there. Instead, it created a FIVETRAN2_PUBLIC schema, which is based on the destination schema name fivetran2.
Now, take a look at the products table. It’s in FIVETRAN2_PUBLIC schema. Before the schema changes in PostgreSQL, these were replicated:
Results in Snowflake: products data

No sku column is present.

After the schema changes, it’s there in the rightmost column. No manual intervention happened in the pipeline.

Results in Snowflake: products data

Below is a data preview for the replicated orders table:

Results in Snowflake: orders data

And finally, for the order_items table:

Results in Snowflake: order items data
Results in BigQuery

Below is what happened after Fivetran replicated the data from HubSpot and Snowflake. There are 2 datasets, one storing HubSpot data and the other for PostgreSQL.

Results in BigQuery: datasets, one storing HubSpot data and the other for PostgreSQL

First, let’s have the replicated HubSpot contacts. All 999 contacts accounted for:

Results in BigQuery: contacts

The 500 products are also there:

Results in BigQuery: products

And the 1797 orders:

Results in BigQuery: orders

Finally, the 3603 order_items:

Results in BigQuery: order items

That ends the Fivetran tests. The Pros and Cons below do not relate to the test, but to the product features.

Pros

  • 900+ pre-built connectors.
  • Automatic schema-change handling.
  • High-throughput database extraction powered by HVR CDC.
  • End-to-end integration with Census (Fivetran Activations) and dbt Labs.

Cons

  • March 2025 shift to per-connector MAR billing significantly raised costs for multi-source setups.
  • $12,000/year minimum contract commitment locks out smaller budgets.
  • Configured connectors are not reusable across different pipelines.
  • The user interface may be okay for developers, but quite intimidating for non-technical users.

Why Choose Airbyte for Open-Source Infrastructure Control?

If you need to run pipelines within your own infrastructure because of compliance, you may want an ETL tool you can run within that environment. And if you want more control through coding and scripting, an open-source ETL tool supported by a large community can be a good choice.

I’ve tried Airbyte before. I tried it with Airbyte Cloud, Airbyte OSS/Core, and PyAirbyte. Airbyte Cloud requires registration. Airbyte OSS needs installation, and this makes my Linux Mint and Ubuntu VMs hang. The most attractive one as a developer is PyAirbyte. I think you will agree with me too.

PyAirbyte doesn’t need Airbyte Cloud account and an installed Airbyte OSS. Just Python, Docker, and Visual Studio. So, after you meet the requirements and created an environment for your project:

> pip install airbyte
> pip install dotenv

That’s it. Then, I started coding.

Best for

Companies with technical and developer teams who want full control of their pipelines with a range of options. They can go for a no-code solution with Airbyte Cloud, or install their own Airbyte instance in their preferred infrastructure with Airbyte Open Source. Or even have more control with coding in Python using PyAirbyte or the Airbyte API.

Companies that fully support open source solutions will find Airbyte attractive.

Rating

There are a few developer and user reviews compared to other ETL tools.

  • G2: 78 reviewers rated 4.4/5
    From G2, referring to Airbyte Cloud: “Users consistently praise the product for its ease of use and flexibility in integrating data from various sources….However, some users note that certain connectors can be buggy, which may require additional troubleshooting.”
  • Capterra: no reviews yet.

Pricing Deep Dive

Pricing in Airbyte depends on the Airbyte option you choose.

  • Free: for PyAirbyte and Airbyte Core/OSS. Only the software is free. Infrastructure and developer costs are not included.
  • Paid: for Airbyte Cloud. Pricing plans include Standard, Plus, and Pro, using capacity-based pricing. You need to contact sales for a tailored quote. For more details, visit the Airbyte pricing page.

For this test, I just downloaded the Python libraries, used free Docker, and free Visual Studio Code. Development price is another story because this test took the longest of all the ETL tools here.

What Does Building a Data Pipeline Look Like in Airbyte?

For this testing, I used Visual Studio Code. Docker needs to be installed and running because the connectors will run in default Docker images managed by Airbyte.

Pipeline Setup Difficulty: 5/5 (Coding in Visual Studio Code using Python and PyAirbyte)
Time to Launch: 3 working days or 24 hours, where 16 hours is for debugging and fixing.

Building the Pipeline in PyAirbyte

I created a folder on my laptop for this new Python project in Visual Studio Code, and I created a new environment. After installing the Airbyte and dotenv packages, I made the .env file for the configurations. They include all parameter settings to successfully connect to HubSpot, Neon Postgres, Snowflake, and BigQuery.

Below is a sample without the actual values:

Building the Pipeline in PyAirbyte

Then, I have to load those environment values using dotenv and assign each value to a Python variable.

Building the Pipeline in PyAirbyte

Then, I prepared the source connectors with config.py imported

source connectors in Airbyte

As you can see, those are the same parameters the other ETL tools needed. The only unique to PyAirbyte is the:

install_if_missing = True

This will install the connectors, if it’s not already present.

There’s also a special setting for HubSpot:

docker_image = True

By default, Snowflake, PostgreSQL, and BigQuery run on default Docker containers. HubSpot is not, so this has to be set, or an error will occur. This took me 2 working days to figure out because the error says nothing about Docker. You will see it in a screenshot later.

Meanwhile, below is the code for setting the destinations:

create Snowflake connector in Airbyte

Then, the following will be the actual replication code from HubSpot and PostgreSQL to Snowflake:

replication code from HubSpot and PostgreSQL to Snowflake in Airbyte

And then going to BigQuery:

replication code from PostgreSQL to BigQuery in Airbyte

All destination setups avoid DuckDB caching (cache=False) and force full refreshes (force_full_refresh=True).

Below is the main function that acts as the orchestrator:

main function that acts as the orchestrator in Airbyte
Runtime Results

I will show you the output from my Visual Studio Code Terminal. Note that the processing progress is within the PyAirbyte library. There’s no need for Python prints.

Below is the HubSpot to Snowflake. It took the initial sync 1 minute and 31 seconds:

HubSpot to Snowflake run time results in Airbyte

Then, PostgreSQL to Snowflake. Initial sync took 1 minute and 2 seconds.

PostgreSQL to Snowflake run time results in Airbyte

Also, HubSpot to BigQuery. This one took 2 minutes and 24 seconds:

HubSpot to BigQuery run time results in Airbyte

And finally, PostgreSQL to BigQuery (1 minute and 19 seconds):

PostgreSQL to BigQuery run time results in Airbyte

Note that it ran in a Linux Mint VM with 6 CPU cores and 16GB of RAM.

The runtime error when docker_image=True is not explicitly set: Config validation error: ‘credentials’ is a required property.

The runtime error when docker_image=True is not explicitly set in Airbyte

This made me think that my credentials format is malformed, but it’s not after checking the documentation several times. After much thought, I concluded that I’m missing a configuration. It proved to be true.

Do you want to try this yourself? You can clone my GitHub repo here -> https://github.com/eisanchez1/hubspot-postgres-to-snowflake-bigquery-pyairbyte-sample.

Results in Snowflake

First, Airbyte didn’t write all the tables in the AIRBYTE schema. Only HubSpot contacts are there. Instead, it followed the schema name from source, which is public in PostgreSQL. See the resulting structure below:

Results in Snowflake: the resulting structure

Notice the output in replicated HubSpot contacts below. The Properties column contains the raw, unflattened JSON values from HubSpot.

Results in Snowflake: contacts

Scrolling to the right, it also has a flattened version of the essential columns. So, this means that Airbyte chose a balance between querying convenience and flexibility in logical schema changes. Email, for example, is one of the columns you don’t need to flatten and it’s an important one for contacts. However, if there are changes in the logical structure of the JSON properties column, Airbyte will capture them.

Results in Snowflake: contacts

Meanwhile, below is data preview prior to the schema change in the products table:

Results in Snowflake: products

Airbyte handled the schema change without changing the pipeline code. See the sku column below:

Results in Snowflake: products

In addition, here’s a preview of the replicated orders table:

Results in Snowflake: orders

And the order_items table:

Results in Snowflake: order items
Results in BigQuery

Since Airbyte follow the source schema name, there is now a public dataset in BigQuery. There’s also the airbyte_internal which is a staging area.

Results in BigQuery

BigQuery has a better preview of JSON columns. Below is a preview of the replicated HubSpot contacts. The email addresses are visible there:

Results in BigQuery: replicated HubSpot contacts

The flattened versions are similar to Snowflake, as you can see below:

Results in BigQuery: contacts

Then, here’s a preview of the products table:

Results in BigQuery: products

And the orders table:

Results in BigQuery: orders

And finally, the order_items table:

Results in BigQuery: order items

All row counts in Snowflake and BigQuery are the same compared to the source.

That ends the testing for Airbyte using PyAirbyte. Below are general Pros and Cons related to Airbyte Cloud, Airbyte OSS, and PyAirbyte.

Pros

  • Complete open-source code control and air-gapped deployment option, good for HIPAA/GDPR control.
  • Vast library of community-maintained connectors.
  • Easy connector development framework for custom internal APIs.
  • No Airbyte account needed using PyAirbyte pipeline development.

Cons

  • “Free” self-hosting hides real infrastructure and DevOps costs ($500–$3,000+/month).
  • Community-maintained connector quality varies.
  • Cloud standard tier limits sync frequency to 1 hour unless upgraded.
  • Coding and scripting may require a lot of time.

Why Choose Matillion for Complex Push-Down Transformations?

Matillion can run an SQL script after your source data is loaded in your data warehouse. This is great for transformations running within the compute resources of your data warehouse. However, this will need engineering effort.

Matillion has Maia, it’s agentic AI. It’s upfront when you start your first pipeline project and will assist you until you finish it. I haven’t tried Matillion much, so there’s a little learning curve needed.

Though Matillion excels in pushdown transformation, we won’t test them here to be consistent with the other ETL tools tests.

Best for

Teams who want AI-assisted data pipeline development, along with a drag-and-drop canvas to further configure each pipeline component. Data transformations running on data warehouse compute shines with Matillion.

Rating

What do users say about Matillion?

  • G2: 4.5/5 with 125 reviews
  • Capterra: 4.3/5 with 111 reviews

Pricing Deep Dive

Pricing tiers in Matillion include Developer, Teams, and Scale. There are free trials for each, but there’s no posted price. Though in Capterra, there’s a basic $2 price. Consumption uses Matillion credits, “the smallest unit of charge, consumed when a customer uses a Matillion resource”, based on Matillion’s FAQ.

For the tests I made with Matillion, the trial gave me 500 Matillion credits. After the test, the remaining credits is 499.9 as shown below:

Matillion consumption overview

Matillion doesn’t have a free tier.

For more information, visit the Matillion pricing page.

What Does Building a Data Pipeline Look Like in Matillion?

In Matillion ETL, there are projects, and projects have environments. These environments are your data’s destination. Each environment will store secrets like passwords and such, and will have pipelines with configured sources..

Pipeline Setup Difficulty: 3/5
Time to Launch: 60–120 minutes

Workflow Steps

Creating pipelines in Matillion is very different compared to the rest of the ETL tools. You have 2 options: You tell Matillion to create/design a new pipeline, and Maia will guide you, or do it yourself.

I started with Maia, but I find it slow and intrusive, so I told Maia to just show me the form, and I’ll do it myself. That’s my opinion. Others find it helpful and make them productive.

When I finally figured it out, the following are the steps (the “do-it-yourself option”):

  1. I created a project and create two environments:
    • One environment for Snowflake
    • Another environment for BigQuery
  2. I created a secret for Neon PostgreSQL password.
  3. Build the pipelines.
    • One pipeline for HubSpot and PostgreSQL to Snowflake.
    • Another pipeline for HubSpot and PostgreSQL to BigQuery.
  4. Run each pipeline to test.
  5. I run the pipelines manually and I didn’t create schedules. But real batch processing pipelines need one in production.
Connector Configurations

Creating a HubSpot connection is the same as Skyvia. Sign in to HubSpot to get authorization. See it below:

Matillion connector configurator

Below is for storing a secret – the Neon PostgreSQL password in the Matillion vault. Note that when you type it, it’s readable. That’s why I covered it. See below:

Matillion connector configurator

Below is the Snowflake environment. Again, it will use Key-pair authentication, and the private key file is crucial to this.

Matillion connector Snowflake configurator

Meanwhile, below is the BigQuery environment. It starts by asking for the project and the target dataset.

Matillion connector BigQuery configurator

Then, you need the service account key for authentication. It won’t be visible like a password.

Matillion connector BigQuery configurator

Validating the connection caused a permission error at first. It took me a while, but I followed the instructions here, and all went well.

Pipeline Setup

Matillion uses drag-and-drop components. The relevant components here are the Load HubSpot and Load Postgres components. For PostgreSQL, each component defines a source table in PostgreSQL and a target table in Snowflake.

See the canvas below:

Matillion pipeline setup

Each Load component needs a connection configuration. It uses JDBC to connect to PostgreSQL. See below:

Matillion pipeline setup: JDBC to connect to PostgreSQL

Then, you need to define the source table so the component can find the source data. This includes the table and columns.

Matillion pipeline setup: JDBC to connect to PostgreSQL

The final part is defining the target table name. The other values will come from the environment settings earlier.

Matillion pipeline setup: defining the target table name

You have to repeat the same for the other 2 PostgreSQL tables:

Matillion pipeline setup: PostgreSQL

When I realized this, I regretted dismissing Maia’s help because it’s repetitive. The good thing here is I only have 1 pipeline for both HubSpot and PostgreSQL going to Snowflake. The other is for BigQuery. This approach is similar to Skyvia’s Data Flow and Control Flow, but without the repetitive configurations.

Since I’m still new to Matillion, I finished the setup in 2 hours, including finding my way in Matillion and correcting the BigQuery permission error.

Runtime Results

The HubSpot and Postgres sources under the Snowflake environment took 21 seconds for the initial sync. See below:

Runtime Results in Matillion

Then, I added the sku column in the PostgreSQL products table and put values in it. Then, I re-ran the pipeline. However, the schema drift was not handled automatically. However, Matillion could detect the new column when I checked it. In other words, the pipeline needs editing. So, I did that, ran the pipeline again, and the new column was reflected in Snowflake.

Runtime Results in Matillion

There’s a different story with BigQuery. There’s a runtime error. Sadly, Matillion didn’t handle the HubSpot column names with characters like “/” and “&” by default, and BigQuery rejects them. I think it can be resolved using an SQL query and creating an alias for those columns. But my time is short now, so what I did was just remove those columns from the replication.

Runtime Results in Matillion:  a runtime error  in BigQuery

And finally, it ran for 16 seconds.

Runtime Results in Matillion
Results in Snowflake

HubSpot contacts in Snowflake have flattened the JSON columns as a result of the Matillion process. See below:

Results in Snowflake: contacts

And here is the preview of the products table after the schema change and the manual pipeline editing:

Results in Snowflake: products

Then, below is for the orders table:

Results in Snowflake: orders

And for order_items table:

Results in Snowflake: order items

All row counts are the same as the source, and all the tables were loaded into the schema we intend it to (the MATILLION schema).

Results in BigQuery

The same flattened columns exist for the HubSpot contacts in BigQuery:

Results in BigQuery: contacts

Same with products table:

Results in BigQuery: products

And with the orders table:

Results in BigQuery: orders

Finally, the order_items table:

Results in BigQuery: order items

Row counts are also the same as the source for all tables.

This ends the Matillion tests. Find below the Pros and Cons based on product features.

Pros

  • Deep push-down transformation leverage directly on Snowflake, Databricks, and Redshift compute.
  • Built specifically for data engineers comfortable with SQL, Python, and dbt.
  • AI-assisted pipeline development with Maia.

Cons

  • Steep learning curve for non-engineers.
  • Dual-billing structure (paying Matillion credit fees on top of warehouse compute costs).

Why Choose Estuary Flow for Sub-Second Streaming & Log-Based CDC?

Estuary Flow is our streaming ETL tool candidate in this test. If you need sub-second streaming because your reports and dashboards need instant updates, this is the tool for you. Log-based CDC also ensures only the updated rows are processed.

I had a few tests done in Estuary, so I know my way around here a little.

Best for

Companies that rely on real-time dashboards and reports with automatic schema-change handling.

Rating

How do Estuary users feel about the product?

  • G2: 4.7/5 with 35 reviews
    From G2: “Users consistently praise the product for its ease of use and responsive support…”
  • Capterra: No reviews found

Pricing Deep Dive

Estuary has a Free Developer tier with 10GB per month and 2 concurrent connector instances. But the moment this is exceeded, a 30-day free trial starts.

Paid tiers include Cloud and Enterprise. Pricing starts at $0.50 per GB + $100 per connector.

When I started, it was free, but I hit the free ceiling, and I entered the free trial. See what happened in the August and September 2026 period below:

Estuary billing

I won’t be eating for a month if I’m asked to pay that price. Good thing it’s a trial. I forgot that this is streaming and the pipelines continue running until I disabled it.

For more information, visit the Estuary pricing page.

What Does Building a Data Pipeline Look Like in Estuary Flow?

Estuary needs sources (or captures) and destinations (or materializations) similar to other ETL tools. But I have to shift my mind from batch to streaming. Of all the candidate ETL tools here, this is the only platform capable of streaming.

Pipeline Setup Difficulty: 3/5
Time to Launch: 20–30 minutes.

Workflow Steps
  1. Create 2 Captures (Sources)
    • One for HubSpot
    • Another for PostgreSQL
  2. Create 2 Materializations (Destinations)
    • One for Snowflake
    • Another for BigQuery
  3. Set the Sync Frequency. It defaults to 30 minutes, but it can be set to zero seconds.
  4. Publish the materializations and let it start running.
Connector and Pipeline Configurations

Let’s start with HubSpot. Same with the others; authorization requires a HubSpot sign-in. See below:

Estuary HubSpot Connector Configurations

The next step is indicating the HubSpot object to replicate. So, we marked contacts.

Estuary HubSpot Connector Configurations

Next is PostgreSQL. I used the same credentials and other parameters.

Estuary PostgreSQL Connector Configurations

Choosing the tables is quite technical. So, I input public.*, meaning all tables set for replication. Like Fivetran and Airbyte, Estuary wants a publication name and replication slot. See them below:

Estuary PostgreSQL Connector Configurations

Then, we have Snowflake for the first destination. The only difference here is the target schema (ESTUARY).

Estuary Snowflake Connector Configurations

Then, we add authorization using the Private key file for TESTUSER.

Estuary Snowflake Connector Configurations

Finally, we have the config for BigQuery below. The JSON credentials used in Matillion are the same here. But the target dataset is estuary_sales_warehouse.

Estuary config for BigQuery

I have a BigQuery permission error below. It pertains to creating BigQuery jobs. The BigQuery Job User permission is only for running jobs. So, to make this quick, I used the BigQuery Data Owner permission.

Estuary BigQuery permission error

But then again, there’s another error. This time, for Snowflake:

Estuary Snowflake error

It seems that Estuary uses Snowflake Stages. So, I added:

GRANT CREATE STAGE ON SCHEMA SALES_WAREHOUSE.ESTUARY TO ROLE PUBLIC;

Then, it went well with Snowflake.

Runtime Results

The tables replicated have the same row counts as the source.

Runtime Results in Estuary

All pipelines are green, meaning it’s working. The good part is, I just noticed it’s done, true to its sub-second promise. Sadly, the duration is not indicated on the page below. I have to dig into the JSON logs, and it’s deep and too technical.

Runtime Results in Estuary
Results in Snowflake

Estuary didn’t flatten the JSON columns from HubSpot. It’s raw, as seen below:

Results in Snowflake: contacts

To unflatten this, you can run a SELECT statement with PARSE_JSON. Here’s a sample:

SELECT
    id::string AS contact_id,
    PARSE_JSON(properties):hs_full_name_or_email::string AS full_name
FROM ESTUARY.CONTACTS
WHERE PARSE_JSON(properties):hs_full_name_or_email IS NOT NULL;

It will extract the CONTACT_id and the FULL_NAME. See the output below:

Snowflake extract the CONTACT_id and the FULL_NAME

Below is a preview of the products table prior to schema change:

Results in Snowflake: products

Then, I added the column while the streaming is enabled. It’s similar to what I did with the other ETL tools, and it added the sku column in the next sync. See below:

Results in Snowflake: products

Meanwhile, here’s the preview for the orders table:

Results in Snowflake: orders

And order_items:

Results in Snowflake: order items

Estuary chose to be defensive for logical schema changes in HubSpot by retaining the raw JSON properties. As for the PostgreSQL tables, it was replicated as-is with additional columns used for processing.

All row counts in Snowflake are the same as the source.

Results in BigQuery

We saw the same results in BigQuery. Unflattened HubSpot contacts columns.

Results in BigQuery: contacts

Same with products table:

Results in BigQuery: products

In orders:

Results in BigQuery: orders

And lastly, in order_items:

Results in BigQuery: order items

That ends the tests in Estuary.

Pros

  • Sub-second streaming architecture for real-time analytics and event-driven apps.
  • Low-impact log-based CDC across modern databases.

Cons

  • Overkill for standard daily or hourly BI reporting pipelines. If you don’t need sub-second updates, a scheduled batch job is recommended.
  • Smaller catalog of SaaS app connectors compared to Skyvia or Fivetran.

How Do You Choose the Right ETL Platform for Your Team?

This test of ETL tools reveals a lot so you can choose which one fits your requirements. It can be summarized to this:

  • Choose Skyvia if:
    You want a no-code tool that handles ingestion, dbt transformations, Reverse ETL, or orchestration at a predictable volume-based price without needing a dedicated data engineering team.
  • Choose Fivetran if:
    You’re a big data company, you have a large enterprise budget ($12k+/yr if on contract), and have a dedicated data engineering team to manage MAR usage.
  • Choose Airbyte if:
    Your DevOps team demands open-source control, air-gapped on-prem deployment, and custom connector development in Python.
  • Choose Matillion if:
    Your data engineers need to build heavy push-down Python/SQL models directly on Snowflake or BigQuery.
  • Choose Estuary if:
    You need sub-second event streaming and real-time database CDC for your dashboard and reports.
Explore Data Warehousing with Skyvia

FAQ for Best ETL Tools

Loader image

Log-based CDC reads database transaction logs for changes, while incremental polling queries changed rows. CDC is usually faster and less taxing for high-volume, frequently changing data.

Not always. Open-source software may have no license cost, but you still pay for infrastructure, maintenance, upgrades, monitoring, security, and engineering time. Managed services shift much of that work to the vendor.

They commonly use a self-hosted agent or connector inside the network. The agent makes outbound connections to the cloud service, so you typically don’t need to expose the database directly to the internet.

Many integrate with dbt by triggering dbt jobs after data ingestion. ETL handles extraction and loading, while dbt transforms the data in the warehouse using SQL models.

It depends on the tool and operation. Some use transactions or staging tables to prevent partial loads; others may leave partially loaded data. Check the platform’s recovery, rollback, and retry behavior.

Share

Edwin Sanchez

Software developer and project manager with a total of 20+ years of software development. His most recent technology preferences include C#, SQL Server BI Stack, Power BI, and Sharepoint. Edwin combines his technical knowledge with his most recent content writing skills to help new breed of technology enthusiasts.