Dagger 0.15: Better errors, Faster filesync, Metrics and much much more…
December 12, 2024
Dec 12, 2024
Today we’re introducing Dagger 0.15, with many usability and performance improvements. We’ve highlighted a few key features below, but there is a very long tail of smaller features and bugfixes that add up to a smoother overall experience. Let’s dive in!
Better Errors
Dagger’s job is to help you ship faster. There are several ways we can do that. First, by making your pipelines faster to develop. Second, by making them faster to run. And third, by making their output more readable, so you can act on it.
In this release we are focusing on improving the most important output of your Dagger pipelines: errors. There is a direct correlation between the quality of the errors presented to you, and how fast you can develop.
With this goal of making your devloop faster, we have improved error reporting in the following ways:
Errors are now at the top of the output
They appear in real-time during execution
They are scrubbed of dagger-specific noise, for maximum readability
They more clearly differentiate warnings from critical errors and application-level issues from system-level issues
They include useful context, like the exact location in the pipeline
When the error is produced by a containerized tool, we show the error that matters (“compilation failed at line X”), and skip the parts that don’t (“your tool failed to execute, exit code 2”)
Here is a visual comparison of the improvements:
Before update:
After update:
These improvements are contained in PR #8442 and PR #9033.
Faster Filesync
Dagger now transfers files much more efficiently between the host system and the engine container, by caching them more efficiently and avoiding redundant data transfers.
As a result, file syncing is significantly faster, requires less memory, and provides quicker feedback loops—particularly useful for large projects or resource-constrained environments.
Under the hood, a more centralized caching approach allows previously synced data to be reused across multiple directories and concurrent sessions. This reduces unnecessary copying, ensures more consistent sync results, and simplifies the overall caching logic. The result is a smoother, more reliable workflow that developers can trust.
These improvements are contained in PR #8818.
Metrics
In addition to traces and logs, Dagger’s telemetry now includes a complete set of metrics, which you can visualize directly in the terminal.
When running in the terminal, Dagger will show the following metrics in real-time, at the individual operation granularity:
CPU (usage and pressure)
Disk utilization
Memory (current and peak usage)
Network (bytes received and transmitted, packet drop rates)
These enhancements make it easier to diagnose issues, fine-tune your workflows, and ensure your pipelines run efficiently. These metrics are first being surfaced in the TUI and will soon be available in Dagger Cloud.
These improvements are contained in PRs #8902 and #8880.
Improved Terminal UI
We’ve improved status reporting to provide clearer and more actionable insights into your pipelines. Key updates include:
Better state tracking: Visual indicators now distinguish between cached and pending states, offering real-time insights into operation statuses.
Accurate duration metrics: Each pipeline step now displays precise execution times, including durations for lazy effects. For example, Container.withExec(args: ["sleep", "10"]) will accurately reflect a 10-second execution period.
Optimized telemetry data: The system generates fewer spans, streamlining telemetry data handling and reducing resource consumption.
Improved log clarity: Logs are now more concise and easier to navigate, facilitating quicker issue identification and resolution.
Collectively these improvements enhance the monitoring and management of pipelines, leading to a more efficient development process.
For a visual comparison of these improvements, refer to the following recordings:
Before update:
After update:
These improvements are contained in PR #8442.
Simpler Networking API
We’ve enhanced Dagger’s service execution by ensuring that services start with their default command arguments when none are specified. This simplifies workflows by allowing services to operate as intended without requiring manual configuration for default settings. Services now just work out of the box, saving you time and eliminating unnecessary steps.
We’ve improved the developer experience when using Dagger’s AsService API. Previously, if you wanted your service to run with its image’s default command (CMD and ENTRYPOINT), you had to jump through hoops—like adding empty WithExec steps—just to ensure it did the right thing. This was confusing and slowed you down.
AsService now seamlessly respects an image’s built-in defaults whenever you don’t provide explicit command arguments. Under the hood, this means we no longer rely on fallback logic that varied depending on prior WithExec calls. Instead, you get a straightforward, “just works” behavior that matches what you’d expect from running the same image with docker run. The result: less friction, clearer expectations, and a smoother path to getting your services up and running.
These improvements are contained in PR #8865.
Additional Usability, Performance, and Reliability Improvements
Dependency Management (PRs #8745 and #8839)
We've been working on CLI enhancements to make dependency management more convenient. Dagger’s dependency management system ensures precise and reproducible builds by pinning all versions to specific Git commits. This guarantees that your pipelines always run with the exact version of a dependency you specify, eliminating surprises caused by unintended updates.
dagger uninstall
, available with this release, allows you to cleanly remove a dependency from your module. Coming soon is dagger update
which will make it easy to keep your dependencies up-to-date within the constraints you want.
TypeScript SDK Improvements(PRs # 8823, 8824, 8675)
We’ve introduced several updates to the TypeScript SDK, making it more powerful, adaptable, and aligned with modern development standards. Here’s what’s new:
Resolving Values by Reference: We’ve refined how the SDK handles type definitions, improving accuracy and reliability. This leads to smoother workflows when working with complex types and fewer errors from type misinterpretation.
It also enables new syntax keywords:
enum
to declare Dagger enumerationtype
for simple data objects.
Since these keywords cannot be decorated, they are registered in the Dagger API when they are used by the module.
// Declare the enum `Example` to the Dagger API
export enum Example {
A = "A",
B = "B",
}
// Declare the type object `Message` to the Dagger API
export type Message {
content: string
}
// Create a default value that can be resolved by Dagger when exported
export const defaultValue = "foo"
@object()
class Test {
@func()
defaultEnumVar(value: Example = Example.A): Example {
return value
}
@func()
defaultStringVar(value: string = defaultValue): Message {
return { content: value }
}
}
Default Node.js Version: The SDK now defaults to the latest LTS Alpine (22.11.0) release of Node.js, ensuring your projects benefit from the most secure, stable, and performant runtime environment.
Custom Base Images: You can now specify a custom runtime image in your module’s package.json, tailoring the SDK to your project’s needs. For example:
{
"dagger": {
"baseImage": "node:23.2.0-alpine@sha256:ecefaffd4706..."
}
}
Note: Currently, only Alpine-based images are supported.
Module Constructor Secret Stability (PR #8948)
We addressed a critical issue where secrets created within a module’s constructor failed during repeated accesses. This problem disrupted workflows that relied on consistent secret retrieval across nested modules. The fix ensures that secrets initialized in module constructors are now reliably accessible across multiple invocations, enhancing the stability and security of secret management within the Dagger engine.
Cache Volumes in Debug Terminal (PR #9034)
Cache volumes are now properly mounted into debug terminal sessions. Previously, when launching an interactive debug session, cache mounts and other non-standard layers were not included, which made some issues harder to debug. With this fix, your debug containers will mirror the actual runtime environment more closely, allowing for more accurate troubleshooting and testing.
Thank you to the user who reported this on our Discord!
Reduced Log Noise (PR #9012)
We’ve refined our logging system to suppress unnecessary error messages related to cgroups. These messages were particularly common in CI environments without cgroups v2 support, cluttering logs and causing confusion.
Resolving Terminal Stability Issues (PR #9013)
We’ve addressed critical issues in Dagger’s engine that were causing goroutine leaks and potential deadlocks during terminal operations.
Improved Handling of Nulls and Enum Validation (PR #8929)
We’ve improved how Dagger handles optional arguments and enums to create a smoother developer experience. Passing null to an optional argument now works as expected, clearly signaling that no default value should be used. Plus, stricter validation ensures enums only accept valid values, preventing common mistakes like accidentally passing null, true, or false.
What’s next?
Thanks to our amazing community of Daggernauts, we continue to see a lot of great feedback, bug reports, and feature requests. Keep it coming!
If you have requests, feedback, or want to contribute, don’t hesitate to join our Discord server.
Thank you for your support, as we continue our mission to transform the world of CI with you!
The Dagger team
Today we’re introducing Dagger 0.15, with many usability and performance improvements. We’ve highlighted a few key features below, but there is a very long tail of smaller features and bugfixes that add up to a smoother overall experience. Let’s dive in!
Better Errors
Dagger’s job is to help you ship faster. There are several ways we can do that. First, by making your pipelines faster to develop. Second, by making them faster to run. And third, by making their output more readable, so you can act on it.
In this release we are focusing on improving the most important output of your Dagger pipelines: errors. There is a direct correlation between the quality of the errors presented to you, and how fast you can develop.
With this goal of making your devloop faster, we have improved error reporting in the following ways:
Errors are now at the top of the output
They appear in real-time during execution
They are scrubbed of dagger-specific noise, for maximum readability
They more clearly differentiate warnings from critical errors and application-level issues from system-level issues
They include useful context, like the exact location in the pipeline
When the error is produced by a containerized tool, we show the error that matters (“compilation failed at line X”), and skip the parts that don’t (“your tool failed to execute, exit code 2”)
Here is a visual comparison of the improvements:
Before update:
After update:
These improvements are contained in PR #8442 and PR #9033.
Faster Filesync
Dagger now transfers files much more efficiently between the host system and the engine container, by caching them more efficiently and avoiding redundant data transfers.
As a result, file syncing is significantly faster, requires less memory, and provides quicker feedback loops—particularly useful for large projects or resource-constrained environments.
Under the hood, a more centralized caching approach allows previously synced data to be reused across multiple directories and concurrent sessions. This reduces unnecessary copying, ensures more consistent sync results, and simplifies the overall caching logic. The result is a smoother, more reliable workflow that developers can trust.
These improvements are contained in PR #8818.
Metrics
In addition to traces and logs, Dagger’s telemetry now includes a complete set of metrics, which you can visualize directly in the terminal.
When running in the terminal, Dagger will show the following metrics in real-time, at the individual operation granularity:
CPU (usage and pressure)
Disk utilization
Memory (current and peak usage)
Network (bytes received and transmitted, packet drop rates)
These enhancements make it easier to diagnose issues, fine-tune your workflows, and ensure your pipelines run efficiently. These metrics are first being surfaced in the TUI and will soon be available in Dagger Cloud.
These improvements are contained in PRs #8902 and #8880.
Improved Terminal UI
We’ve improved status reporting to provide clearer and more actionable insights into your pipelines. Key updates include:
Better state tracking: Visual indicators now distinguish between cached and pending states, offering real-time insights into operation statuses.
Accurate duration metrics: Each pipeline step now displays precise execution times, including durations for lazy effects. For example, Container.withExec(args: ["sleep", "10"]) will accurately reflect a 10-second execution period.
Optimized telemetry data: The system generates fewer spans, streamlining telemetry data handling and reducing resource consumption.
Improved log clarity: Logs are now more concise and easier to navigate, facilitating quicker issue identification and resolution.
Collectively these improvements enhance the monitoring and management of pipelines, leading to a more efficient development process.
For a visual comparison of these improvements, refer to the following recordings:
Before update:
After update:
These improvements are contained in PR #8442.
Simpler Networking API
We’ve enhanced Dagger’s service execution by ensuring that services start with their default command arguments when none are specified. This simplifies workflows by allowing services to operate as intended without requiring manual configuration for default settings. Services now just work out of the box, saving you time and eliminating unnecessary steps.
We’ve improved the developer experience when using Dagger’s AsService API. Previously, if you wanted your service to run with its image’s default command (CMD and ENTRYPOINT), you had to jump through hoops—like adding empty WithExec steps—just to ensure it did the right thing. This was confusing and slowed you down.
AsService now seamlessly respects an image’s built-in defaults whenever you don’t provide explicit command arguments. Under the hood, this means we no longer rely on fallback logic that varied depending on prior WithExec calls. Instead, you get a straightforward, “just works” behavior that matches what you’d expect from running the same image with docker run. The result: less friction, clearer expectations, and a smoother path to getting your services up and running.
These improvements are contained in PR #8865.
Additional Usability, Performance, and Reliability Improvements
Dependency Management (PRs #8745 and #8839)
We've been working on CLI enhancements to make dependency management more convenient. Dagger’s dependency management system ensures precise and reproducible builds by pinning all versions to specific Git commits. This guarantees that your pipelines always run with the exact version of a dependency you specify, eliminating surprises caused by unintended updates.
dagger uninstall
, available with this release, allows you to cleanly remove a dependency from your module. Coming soon is dagger update
which will make it easy to keep your dependencies up-to-date within the constraints you want.
TypeScript SDK Improvements(PRs # 8823, 8824, 8675)
We’ve introduced several updates to the TypeScript SDK, making it more powerful, adaptable, and aligned with modern development standards. Here’s what’s new:
Resolving Values by Reference: We’ve refined how the SDK handles type definitions, improving accuracy and reliability. This leads to smoother workflows when working with complex types and fewer errors from type misinterpretation.
It also enables new syntax keywords:
enum
to declare Dagger enumerationtype
for simple data objects.
Since these keywords cannot be decorated, they are registered in the Dagger API when they are used by the module.
// Declare the enum `Example` to the Dagger API
export enum Example {
A = "A",
B = "B",
}
// Declare the type object `Message` to the Dagger API
export type Message {
content: string
}
// Create a default value that can be resolved by Dagger when exported
export const defaultValue = "foo"
@object()
class Test {
@func()
defaultEnumVar(value: Example = Example.A): Example {
return value
}
@func()
defaultStringVar(value: string = defaultValue): Message {
return { content: value }
}
}
Default Node.js Version: The SDK now defaults to the latest LTS Alpine (22.11.0) release of Node.js, ensuring your projects benefit from the most secure, stable, and performant runtime environment.
Custom Base Images: You can now specify a custom runtime image in your module’s package.json, tailoring the SDK to your project’s needs. For example:
{
"dagger": {
"baseImage": "node:23.2.0-alpine@sha256:ecefaffd4706..."
}
}
Note: Currently, only Alpine-based images are supported.
Module Constructor Secret Stability (PR #8948)
We addressed a critical issue where secrets created within a module’s constructor failed during repeated accesses. This problem disrupted workflows that relied on consistent secret retrieval across nested modules. The fix ensures that secrets initialized in module constructors are now reliably accessible across multiple invocations, enhancing the stability and security of secret management within the Dagger engine.
Cache Volumes in Debug Terminal (PR #9034)
Cache volumes are now properly mounted into debug terminal sessions. Previously, when launching an interactive debug session, cache mounts and other non-standard layers were not included, which made some issues harder to debug. With this fix, your debug containers will mirror the actual runtime environment more closely, allowing for more accurate troubleshooting and testing.
Thank you to the user who reported this on our Discord!
Reduced Log Noise (PR #9012)
We’ve refined our logging system to suppress unnecessary error messages related to cgroups. These messages were particularly common in CI environments without cgroups v2 support, cluttering logs and causing confusion.
Resolving Terminal Stability Issues (PR #9013)
We’ve addressed critical issues in Dagger’s engine that were causing goroutine leaks and potential deadlocks during terminal operations.
Improved Handling of Nulls and Enum Validation (PR #8929)
We’ve improved how Dagger handles optional arguments and enums to create a smoother developer experience. Passing null to an optional argument now works as expected, clearly signaling that no default value should be used. Plus, stricter validation ensures enums only accept valid values, preventing common mistakes like accidentally passing null, true, or false.
What’s next?
Thanks to our amazing community of Daggernauts, we continue to see a lot of great feedback, bug reports, and feature requests. Keep it coming!
If you have requests, feedback, or want to contribute, don’t hesitate to join our Discord server.
Thank you for your support, as we continue our mission to transform the world of CI with you!
The Dagger team
Today we’re introducing Dagger 0.15, with many usability and performance improvements. We’ve highlighted a few key features below, but there is a very long tail of smaller features and bugfixes that add up to a smoother overall experience. Let’s dive in!
Better Errors
Dagger’s job is to help you ship faster. There are several ways we can do that. First, by making your pipelines faster to develop. Second, by making them faster to run. And third, by making their output more readable, so you can act on it.
In this release we are focusing on improving the most important output of your Dagger pipelines: errors. There is a direct correlation between the quality of the errors presented to you, and how fast you can develop.
With this goal of making your devloop faster, we have improved error reporting in the following ways:
Errors are now at the top of the output
They appear in real-time during execution
They are scrubbed of dagger-specific noise, for maximum readability
They more clearly differentiate warnings from critical errors and application-level issues from system-level issues
They include useful context, like the exact location in the pipeline
When the error is produced by a containerized tool, we show the error that matters (“compilation failed at line X”), and skip the parts that don’t (“your tool failed to execute, exit code 2”)
Here is a visual comparison of the improvements:
Before update:
After update:
These improvements are contained in PR #8442 and PR #9033.
Faster Filesync
Dagger now transfers files much more efficiently between the host system and the engine container, by caching them more efficiently and avoiding redundant data transfers.
As a result, file syncing is significantly faster, requires less memory, and provides quicker feedback loops—particularly useful for large projects or resource-constrained environments.
Under the hood, a more centralized caching approach allows previously synced data to be reused across multiple directories and concurrent sessions. This reduces unnecessary copying, ensures more consistent sync results, and simplifies the overall caching logic. The result is a smoother, more reliable workflow that developers can trust.
These improvements are contained in PR #8818.
Metrics
In addition to traces and logs, Dagger’s telemetry now includes a complete set of metrics, which you can visualize directly in the terminal.
When running in the terminal, Dagger will show the following metrics in real-time, at the individual operation granularity:
CPU (usage and pressure)
Disk utilization
Memory (current and peak usage)
Network (bytes received and transmitted, packet drop rates)
These enhancements make it easier to diagnose issues, fine-tune your workflows, and ensure your pipelines run efficiently. These metrics are first being surfaced in the TUI and will soon be available in Dagger Cloud.
These improvements are contained in PRs #8902 and #8880.
Improved Terminal UI
We’ve improved status reporting to provide clearer and more actionable insights into your pipelines. Key updates include:
Better state tracking: Visual indicators now distinguish between cached and pending states, offering real-time insights into operation statuses.
Accurate duration metrics: Each pipeline step now displays precise execution times, including durations for lazy effects. For example, Container.withExec(args: ["sleep", "10"]) will accurately reflect a 10-second execution period.
Optimized telemetry data: The system generates fewer spans, streamlining telemetry data handling and reducing resource consumption.
Improved log clarity: Logs are now more concise and easier to navigate, facilitating quicker issue identification and resolution.
Collectively these improvements enhance the monitoring and management of pipelines, leading to a more efficient development process.
For a visual comparison of these improvements, refer to the following recordings:
Before update:
After update:
These improvements are contained in PR #8442.
Simpler Networking API
We’ve enhanced Dagger’s service execution by ensuring that services start with their default command arguments when none are specified. This simplifies workflows by allowing services to operate as intended without requiring manual configuration for default settings. Services now just work out of the box, saving you time and eliminating unnecessary steps.
We’ve improved the developer experience when using Dagger’s AsService API. Previously, if you wanted your service to run with its image’s default command (CMD and ENTRYPOINT), you had to jump through hoops—like adding empty WithExec steps—just to ensure it did the right thing. This was confusing and slowed you down.
AsService now seamlessly respects an image’s built-in defaults whenever you don’t provide explicit command arguments. Under the hood, this means we no longer rely on fallback logic that varied depending on prior WithExec calls. Instead, you get a straightforward, “just works” behavior that matches what you’d expect from running the same image with docker run. The result: less friction, clearer expectations, and a smoother path to getting your services up and running.
These improvements are contained in PR #8865.
Additional Usability, Performance, and Reliability Improvements
Dependency Management (PRs #8745 and #8839)
We've been working on CLI enhancements to make dependency management more convenient. Dagger’s dependency management system ensures precise and reproducible builds by pinning all versions to specific Git commits. This guarantees that your pipelines always run with the exact version of a dependency you specify, eliminating surprises caused by unintended updates.
dagger uninstall
, available with this release, allows you to cleanly remove a dependency from your module. Coming soon is dagger update
which will make it easy to keep your dependencies up-to-date within the constraints you want.
TypeScript SDK Improvements(PRs # 8823, 8824, 8675)
We’ve introduced several updates to the TypeScript SDK, making it more powerful, adaptable, and aligned with modern development standards. Here’s what’s new:
Resolving Values by Reference: We’ve refined how the SDK handles type definitions, improving accuracy and reliability. This leads to smoother workflows when working with complex types and fewer errors from type misinterpretation.
It also enables new syntax keywords:
enum
to declare Dagger enumerationtype
for simple data objects.
Since these keywords cannot be decorated, they are registered in the Dagger API when they are used by the module.
// Declare the enum `Example` to the Dagger API
export enum Example {
A = "A",
B = "B",
}
// Declare the type object `Message` to the Dagger API
export type Message {
content: string
}
// Create a default value that can be resolved by Dagger when exported
export const defaultValue = "foo"
@object()
class Test {
@func()
defaultEnumVar(value: Example = Example.A): Example {
return value
}
@func()
defaultStringVar(value: string = defaultValue): Message {
return { content: value }
}
}
Default Node.js Version: The SDK now defaults to the latest LTS Alpine (22.11.0) release of Node.js, ensuring your projects benefit from the most secure, stable, and performant runtime environment.
Custom Base Images: You can now specify a custom runtime image in your module’s package.json, tailoring the SDK to your project’s needs. For example:
{
"dagger": {
"baseImage": "node:23.2.0-alpine@sha256:ecefaffd4706..."
}
}
Note: Currently, only Alpine-based images are supported.
Module Constructor Secret Stability (PR #8948)
We addressed a critical issue where secrets created within a module’s constructor failed during repeated accesses. This problem disrupted workflows that relied on consistent secret retrieval across nested modules. The fix ensures that secrets initialized in module constructors are now reliably accessible across multiple invocations, enhancing the stability and security of secret management within the Dagger engine.
Cache Volumes in Debug Terminal (PR #9034)
Cache volumes are now properly mounted into debug terminal sessions. Previously, when launching an interactive debug session, cache mounts and other non-standard layers were not included, which made some issues harder to debug. With this fix, your debug containers will mirror the actual runtime environment more closely, allowing for more accurate troubleshooting and testing.
Thank you to the user who reported this on our Discord!
Reduced Log Noise (PR #9012)
We’ve refined our logging system to suppress unnecessary error messages related to cgroups. These messages were particularly common in CI environments without cgroups v2 support, cluttering logs and causing confusion.
Resolving Terminal Stability Issues (PR #9013)
We’ve addressed critical issues in Dagger’s engine that were causing goroutine leaks and potential deadlocks during terminal operations.
Improved Handling of Nulls and Enum Validation (PR #8929)
We’ve improved how Dagger handles optional arguments and enums to create a smoother developer experience. Passing null to an optional argument now works as expected, clearly signaling that no default value should be used. Plus, stricter validation ensures enums only accept valid values, preventing common mistakes like accidentally passing null, true, or false.
What’s next?
Thanks to our amazing community of Daggernauts, we continue to see a lot of great feedback, bug reports, and feature requests. Keep it coming!
If you have requests, feedback, or want to contribute, don’t hesitate to join our Discord server.
Thank you for your support, as we continue our mission to transform the world of CI with you!
The Dagger team