Making SSIS Packages Faster

The package finishes late, but the last destination is blamed without evidence. Making SSIS packages faster starts by timing each source, transform, and destination. Fast load and sensible buffers help only after the slow step is identified.

A tall hourglass on a windowsill, the upper bulb full of sand and a thin stream falling through the narrow neck.

Measure Each Step Before Making SSIS Packages Faster

Record package execution, task start and end, source rows, rejected rows, and destination rows. A package can wait on a source query before the data flow begins. It can also spend most time writing an indexed destination. Without step timing, buffer changes are guesses.

I start with SSISDB execution history and the database waits during a slow run. Which component owns the longest interval? Fix that before changing every setting in the project. A stopwatch on the wrong task is decorative.

Read SSISDB Execution History

The SSIS catalog records executions and status. Use it to identify repeated slow runs and compare the same package across days. Status values need interpretation with messages and step data. A package that finished successfully can still have rejected rows or an unexpected count.

This query returns recent executions. Run it where SSISDB is installed and permissions allow access. I attach the source batch and expected row count to the run log for a complete picture.

SELECT TOP (30) execution_id,
       folder_name, project_name, package_name,
       start_time, end_time, status
FROM SSISDB.catalog.executions
ORDER BY execution_id DESC;

Keep Source Queries Efficient

A data flow cannot outrun a source query that scans too much or sorts unnecessarily. Run the source SQL on its own with representative parameters and inspect its plan. Select only required columns. Push filters into the source where they preserve meaning and reduce transfer. Avoid forcing row-by-row lookups after extraction.

I compare source row count with expected volume before tuning downstream buffers. A package that reads ten times too many rows has a logic problem. Larger buffers can carry the extra rows faster, but the work should not exist.

Use Fast Load to Make SSIS Packages Faster at the Destination

The OLE DB destination fast-load mode batches inserts. Its table-lock and commit-size options affect throughput, locking, log use, and rollback cost. Check constraints and triggers as part of the test. Fast load into a narrow staging heap can be very different from writing a populated fact table with many indexes.

I test batch sizes under realistic concurrency and record destination log waits. A maximum insert commit size of zero can make one large transaction, which is risky for failure recovery. Choose the size that the job can restart and the server can sustain.

Time every stage before tuning one: a diagram about the SSIS packages faster

Treat Buffer Settings as Measurements

DefaultBufferSize and DefaultBufferMaxRows influence how many rows fit in each pipeline buffer. Row width, including large values, determines actual capacity. Start with defaults and use data flow performance counters or SSIS logging to see whether buffers are the limiting factor. Increasing them blindly can raise memory pressure and reduce concurrency.

I inspect the longest string columns and unused fields first. Narrowing the pipeline can help more than raising a buffer limit. A wider pipe is not useful when the destination drain is blocked.

Avoid Row-by-Row Commands to Keep SSIS Packages Faster

An OLE DB Command transform can execute SQL for each row. That is convenient for a tiny lookup and costly for a large flow. Stage rows and use a set-based UPDATE or INSERT instead. Cache or join reference data where appropriate, after checking memory use and lookup miss behavior.

The example updates staged rows from a reference table in one statement. It assumes stable keys and a unique reference match. I count unmatched rows separately so data quality does not disappear inside a fast transform.

UPDATE s
SET s.CustomerKey = d.CustomerKey
FROM dbo.SaleStage AS s
JOIN dbo.DimCustomer AS d
  ON d.SourceCustomerID = s.SourceCustomerID
WHERE s.CustomerKey IS NULL;

Watch Parallel Flows Carefully

Independent data flows can run concurrently when source, destination, log, and memory have room. Too much parallelism can saturate the same database or file share. A package-level setting does not create capacity. Measure throughput and waits as concurrency rises.

I test a controlled increase, then stop when total package time stops improving. A single package finishing faster while two others slow down is not a win for the nightly window. The schedule, not just one task, is the unit of success.

Inspect Failure Messages

SSISDB event messages can show errors, warnings, and component details for an execution. Use a known execution_id when investigating. Protect sensitive parameter values in logs. A destination failure that rolls back a large batch needs both the error and the failed row range to recover safely.

The query returns recent messages for one execution. Replace the ID with a real run from the execution history.

DECLARE @execution_id bigint = 1;
SELECT message_time, message_type,
       message_source_name, message
FROM SSISDB.catalog.event_messages
WHERE operation_id = @execution_id
ORDER BY message_time;

Change One Bottleneck at a Time

Capture baseline run time, row counts, CPU, memory, log I/O, and errors. Change the source query, fast-load mode, buffer setting, or transform design one at a time. Repeat the same data volume. A faster run with fewer rows is a data loss problem, not a tuning success.

Making SSIS packages faster comes from measured steps and set-based work. Keep the package restartable and its output verifiable. The best performance change makes the load boring at the expected hour.

Before increasing buffer sizes, inspect row widths, lookup behavior, and destination commit settings. A large buffer can consume memory without improving a flow limited by one slow source query. Fast load helps the destination, but it cannot speed a row-by-row transform upstream.

I change one setting and rerun the same input under comparable conditions. SSISDB step timings and SQL Server waits together show whether the bottleneck moved. Watch the package after the change for spills, memory pressure, and blocking on the target. Faster SSIS packages that hold locks longer can make the whole nightly schedule worse. The package is part of a workload, not an isolated race. Keep a record of the baseline and the measured result on the actual server.

Ask whether the package is waiting on the source, transformation, target, or another scheduled workload. Check each wait before increasing parallel tasks. A faster component does not guarantee a faster nightly run.

Inspect source and destination SQL plans when a data flow is slow. SSIS can spend most of its time waiting on a query or an indexed target table. Package tuning cannot remove that database cost without changing the query or load design.

Related reading on this blog: Huge Size of SSISDB: Catalog Database SSISDB Cleanup Script and Lookups in a Data Load: Cached, Uncached and Wrong.

What a faster run proves: a checklist on the SSIS packages faster

A faster package is not a shorter progress bar, it is a complete and correct load with less measured work.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.

ETL, SQL Performance, SQL Server, SSIS
Previous Post
Performance Baseline in SQL Server: Measure Before You Tune
Next Post
SQL SERVER – Introduction of Showplan Warning

Related Posts

1 Comment. Leave new

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.