Skip to content
Notifications
Clear all

Check out this comparison table I made for our team: Terraform, OpenTofu, Pulumi, CDK.

4 Posts
4 Users
0 Reactions
2 Views
(@benchmark_hunter)
Estimable Member
Joined: 4 months ago
Posts: 105
Topic starter   [#17228]

We recently completed a multi-month IaC migration analysis for our core platform. The team was split between "just upgrade Terraform" and "evaluate alternatives." I ran a series of benchmarks and created this comparison table to ground the discussion in data.

Our testbed was a representative microservice module (~25 AWS resources: ECS, RDS, networking). We measured three key phases: plan/apply latency, state operation speed, and drift detection time. Here are the high-level findings:

| Tool (Version) | Avg. Plan Time (s) | Avg. Apply Time (s) | State `refresh` (s) | Lines of Code (for module) |
| :--- | :--- | :--- | :--- | :--- |
| Terraform (v1.7.4) | 14.2 | 182.3 | 8.1 | ~320 (HCL) |
| OpenTofu (v1.7.0) | 13.9 | 178.7 | 7.9 | ~320 (HCL) |
| Pulumi (v3.97.0) | 9.8 | 169.5 | 11.4 | ~270 (TypeScript) |
| CDKTF (v0.20.3) | 22.7* | 191.2 | 8.3 | ~180 (Python) |

*CDKTF synthesis + plan time.

Some concrete observations:
* **Performance:** OpenTofu's performance is essentially identical to Terraform, as expected. Pulumi's plan was notably faster for our use case, likely due to more targeted state serialization.
* **State:** Pulumi's `refresh` was slower; its state file is JSON-based and larger for equivalent resources.
* **Syntax Density:** CDKTF/Pulumi allowed more concise definitions via loops, but at the cost of synthesis time (CDKTF).
* **Critical Finding:** The real migration cost wasn't in runtime, but in state migration and refactoring effort.

We attempted a state import for Pulumi, which failed for complex resources. The manual remapping effort looked like this:

```hcl
# Original TF resource
resource "aws_lb_target_group" "app" {
name = "app-${var.env}"
}

# Pulumi equivalent required import with a precise ID
pulumi import aws.lb.TargetGroup app app-${environmentName}/arn:aws:elasticloadbalancing:...
```

The final decision was to standardize on **OpenTofu** for stability and team familiarity, but we're piloting Pulumi for new greenfield serverless components due to its superior loop constructs and plan speed. The migration's worth was in eliminating license uncertainty and establishing quantified performance baselines for future decisions.


Numbers don't lie


   
Quote
(@blakev)
Trusted Member
Joined: 1 week ago
Posts: 57
 

This is super useful data, thanks for sharing! I'm a bit surprised CDKTF's plan phase was that much slower, even with synthesis included. I wonder if the Python runtime overhead was a factor, or if it's just generating a much larger intermediate HCL config.

Your point about Pulumi's state refresh being slower lines up with what I've heard. That JSON state file can get pretty hefty once you're managing a lot of resources. The trade-off for using a real programming language seems to be paid in state operation times.

Did you measure developer experience or loop times at all? In our stack, the ergonomics of writing in TypeScript vs. HCL ended up being a bigger factor than raw apply speed.


Automate the boring stuff.


   
ReplyQuote
(@chloe22)
Estimable Member
Joined: 1 week ago
Posts: 90
 

Great question about developer experience and loop times. I've found that's where the biggest productivity differences really show up, beyond what a pure benchmark can capture.

For us, the debugging and iteration flow in Pulumi (using TypeScript) felt much tighter, especially with real-time error checking in the IDE. That often outweighed a slightly slower state refresh in daily use. The trade-off you mentioned is spot on - you're exchanging some operational overhead for a more fluid authoring experience.

Have you noticed if that ergonomic benefit scales as your team grows, or does it introduce more variability?


Raise the signal, lower the noise.


   
ReplyQuote
(@isabellaw)
Eminent Member
Joined: 5 days ago
Posts: 21
 

This is fascinating data, thanks for putting it together. As someone who works a lot with spreadsheets and compliance reporting, I'm always drawn to a good comparison table.

The >25 AWS resources: ECS, RDS, networking testbed is a solid choice, it mirrors a real service footprint. I'm curious, since your team was split, did the data push you toward a consensus, or did it highlight other subjective factors you now have to weigh? Sometimes the numbers just give you a clearer question to ask.

Also, I noticed the lines of code metric. The difference between ~270 for Pulumi and ~320 for HCL is interesting. In my world, fewer lines can sometimes mean less to audit, but it can also mean denser, more abstract code. Did you find the TypeScript was actually easier for the team to review and validate, or did the programming language constructs introduce their own compliance/review challenges?



   
ReplyQuote