July 2025 in Amsterdam had a Java evening and a dbt evening, two weeks apart. I photographed the agenda slides at both and recorded most of the talks, so this post combines what the slides said with what I heard, plus a few notes checked against the official documentation. I only name people where a name is printed on a slide, and I attribute a talk to a speaker only when the agenda title and the recording clearly match.
Netherlands dbt Meetup, 8 July 2025
The title slide read âNetherlands dbt Meetup, 8 July 2025, 5.30 - 8.00 pmâ, âHosted at the Snowflake Experience Centre in Amsterdam Zuidâ. It listed three speakers: Jon Su (Snowplow), Hassan Dibani (Snowflake) and Bart van Delft (dbt Labs). The room had a screen on each side of the wall: one with the slide, one with a wide camera view of the room.

The Netherlands dbt Meetup title slide: 8 July 2025, hosted by Snowflake in Amsterdam Zuid.
One slide in the room read âdbt Labs acquires SDF Labs to accelerate the dbt developer experienceâ, with the dbt Labs and SDF logos. It sets the scene for the third talk below. The evening was the 13th edition of the dbt meetup, according to the hostâs closing remarks.

The room during the dbt Labs slide.
dbt projects on Snowflake (Hassan Dibani, Snowflake)
The first talk I recorded was from the Snowflake speaker, Hassan Dibani on the agenda, about dbt Projects on Snowflake, which he said was announced at Snowflake Summit a couple of months earlier. The idea is to run dbt Core next to the data, inside the same governed Snowflake environment. The Snowflake documentation describes it as bringing the dbt lifecycle into Snowflake, with a dbt project as a schema-level object, development in Snowflake Workspaces, scheduling with native tasks, and run history and logs for monitoring.
What he demonstrated, in my words:
- One system. Teams that have to learn Git, an orchestrator and a runner can start from the Snowflake UI. The same access rules that apply to the data apply to the job, and the runs show up like any other query in the account history.
- Workspaces. A browser IDE where you plug in a Git repository, pick a target profile (dev, test or prod), and run compile, deps, run and test from the UI. Compiled SQL opens side by side with the model, and you can see where the model sits in the DAG. You can also commit and push from the IDE.
- Scheduling. A schedule creates a Snowflake task behind the scenes, so you get run history and failure details there. His demo run failed once because a colleague had put a resource monitor on the warehouse.
- Positioning. He was clear that this targets the T of ELT, for data that already sits in Snowflake. For external sources he pointed to the dbt platform, or to dbt Core with your own orchestration, and mentioned Snowflakeâs own ingestion tooling.
- Demo project. A public âTasty Bytesâ repository with a setup script, shared through a QR code on the last slide.
When the host asked when to choose this over dbt Core or the dbt platform, the answer was the speakerâs philosophy: run the transformation where the data already lives, with the same governance and security.
Modelling event data (Jon Su, Snowplow)
The second talk came from a Solutions Architect at Snowplow (the agenda slide names Jon Su as the Snowplow speaker). Snowplow describes itself as customer data infrastructure: collect events from websites, apps and services and stream them into a warehouse such as Snowflake or Databricks, where customers build their models. The recording of this talk is short on detail because part of it looped, so I only have the opening argument:
- Event data is about sequences and state, not isolated rows. You want to follow what happens across events, unlike a typical transactional record.
- Behavioural data is raw, atomic, unopinionated and high-volume, and the speaker called it âfuel for AIâ because it explains what someone did and helps predict what they will do next.
- Application-first tracking design, where you define events from what you can see on a page, is easy for non-technical stakeholders but has cautionary tales around data quality. The speaker introduced entities as a way to describe the context an event happens in.
dbt Fusion and the SDF acquisition (Bart van Delft, dbt Labs)
The third talk, from the dbt Labs speaker (Bart van Delft on the agenda, and the host addressed him as Bart in the Q&A), is the one the SDF slide belongs to. My recording starts partway through, but the main thread is clear: the dbt Fusion engine, built by combining SDFâs SQL comprehension technology with dbtâs widely adopted framework. The speaker pointed to two background sources: a podcast episode with one of the SDF founders on compilers, and a talk by an SDF co-founder on how the engine learned the behaviour of SQL functions across databases.
Practical notes from the talk:
- Trying it. Fusion is a binary you can download, usable from the dbt VS Code extension with adapters such as Snowflake, Databricks or BigQuery. If you are on the dbt platform, move to the latest version, run the deprecations autofix script and pick the environments to upgrade. For dbt Core, the speakerâs route was to go to 1.10, run the autofix, then install Fusion.
- Soft blockers at the time (July 2025). No Python models yet, and gaps around semantic model development and some integrations. His summary of the engineering pace over four or five months was âquite insaneâ, in a good way.
- Licensing. The VS Code extension is free below a user cap of 15, with an agreement needed for larger organisations. The engine binary moves away from Apache 2.0 to what he called âavailable sourceâ, free to use but not to offer as a managed service. dbtâs own documentation on the Fusion components describes the source-available parts under the Elastic License 2.0 and the proprietary VS Code extension as free for up to 15 users, so check the current terms before you adopt it.
- Snowflake. The speaker said Snowflake is part of the dbt Fusion partner programme, so Fusion should reach dbt Projects on Snowflake in time, with no dates promised. He also mentioned tight integrations with Databricks, Redshift and Google.
- Q&A. One question was whether Fusion works with open-source Spark; the answer was that Python models are not supported yet and Spark SQL is probably fine, but he was not sure. Another asked about exposing the language server as an API or for MCP and AI assistants; the speaker said the language server runs locally in the VS Code extension and he did not know of firm plans.
The host closed by announcing a webinar on moving from legacy BI tools, asking for hosts and first-time speakers for future editions, and the usual group photo.
What dbt is, from the docs
For readers who have not met it, here is what the dbt documentation says. dbt is the T in ELT: you write SQL select statements, and dbt handles materialisation, transactions, DDL and schema changes, so the transformation runs inside your data platform without moving the data out. Models can reference each other, which is how dbt builds the dependency graph. It also covers data quality tests, auto-generated documentation, packages, macros and hooks, and fits into version control and CI/CD.
The data tests page lists four generic tests that ship with dbt: unique, not_null, accepted_values and relationships (referential integrity between two tables). You can also write singular tests: one-off SQL files in the tests/ directory that return the failing rows. dbt test runs them all.
The docs also describe the dbt Fusion engine: a Rust-based engine that powers dbt v2. It understands SQL natively across dialects and catches errors before the code reaches your warehouse. The docs list autocomplete, inline errors and column-level tracing among its editor features, and an Apache 2.0 open source CLI runtime foundation. The docs page does not mention the SDF Labs acquisition, so I am not drawing a link from the slide to that page.
My take: the four built-in tests are the cheapest data quality investment there is. unique and not_null on every primary key, and relationships on every foreign key, catch a large share of broken pipelines before a dashboard does. Add singular tests only for business rules.

The Snowflake logo wall at the entrance.

Food at the meetup.
Amsterdam JUG, 22 July 2025
The Amsterdam JUG evening had a four-talk agenda on screen, with Miro branding (âGet Great Doneâ) on the second display:
| Time | Speaker (as printed) | Talk |
|---|---|---|
| 19:00 - 19:30 | Ko Turk | âAsynchronous Job Processing in Java with JobRunrâ |
| 19:30 - 20:00 | John Ceccarelli | âJava Performance: Beyond Simple Request Latenciesâ |
| 20:15 - 20:45 | Sergey Chernov | âMonolith Server Build Optimizationâ |
| 20:45 - 21:15 | Murat Ozkan | âBreaking Up the Monolith: A Developerâs Guide to Taming the Beastâ |

The agenda with the audience. I did not photograph the talk slides, so what follows comes from my recordings.
The recordings start after the first talk, so I have no content from the JobRunr session. For context, the JobRunr site describes it as a Java library for durable background jobs backed by your existing database; the open source edition is LGPL 3.0 and there is a commercial Pro edition. The typical pattern is a fire-and-forget call such as BackgroundJob.enqueue(...) that persists the job so it survives restarts.
Java performance beyond request latency
The recording of the second talk matches the agenda title, and the speaker introduced himself as a senior director of product management at Azul. That fits the agendaâs John Ceccarelli, so I name him on the agendaâs evidence. Treat vendor claims as the speakerâs.
His framing: performance is more than median latency. Using a racing analogy, he listed top speed, acceleration (how fast you get to full speed), consistency (the P99 outliers), efficiency (CPU per transaction, which ties to scaling and sustainability) and memory. Then he followed a container through its day:
- Scheduling and image pull. Waiting for a node can take minutes on some systems; keeping spare nodes, or using serverless platforms, mostly solves it. Layered images and node caching take care of the pull.
- Startup. Initialisation, such as hydrating caches, can be slow. He mentioned a fintech whose start took about an hour, brought down to seconds with the techniques below.
- Warm-up. The JIT compiler turns portable bytecode into optimised machine code only after a method has been called many times, and it speculates. When the traffic pattern changes, it throws optimisations away (a deoptimisation) and starts again. The JVM also splits CPU between serving requests and compiling, which is why containers are often sized with headroom for the start.
- Steady state. Stop-the-world garbage collection is a likely cause of periodic outliers, and the bigger the heap, the longer the pause.
The tools he walked through, from least to most invasive:
- AOT profiling. Save the profiling information between runs so the JVM does not start from zero, or as he put it with a Memento joke, give the JVM a long-term memory. He described it as coming in JDK 25; the OpenJDK page for JEP 515 lists Ahead-of-Time Method Profiling as delivered in release 25, as part of Project Leyden. The trade-off he showed: a longer first minute, then a faster ramp-up and no deoptimisation storm if traffic stays similar. He also mentioned limiting the CPU the JIT may use after the readiness probe passes.
- Externalised JIT. Offload compilation to a service with a cache (Azul Optimizer Hub, or the OpenJ9 JIT server), best combined with AOT profiling, so the client container needs fewer cores.
- GraalVM Native Image. Closed-world ahead-of-time compilation: instant start, but slower peak performance than a dynamic JIT, and no code generated at runtime.
- CRaC (coordinated restore at checkpoint). Snapshot a warmed-up process and restore it; AWS Lambda SnapStart builds on this idea. It needs care with things that cannot be snapshotted, such as open connections. See the CRaC project page.
- Garbage collectors. Generational ZGC arrived in JDK 21 (JEP 439), which he called âquite respectableâ.
In the Q&A on AOT profiling, he said managing profiles is the hardest part: a code change invalidates a profile, so you version the profile name and regenerate it, and Azulâs Optimizer Hub has an orchestrator that picks profiles across a fleet.
My take: the useful message is to measure the warm-up phase, not just steady state. If your autoscaler adds pods during a spike, the new pods are at their slowest exactly when you need them.
Speeding up the Miro monolith build
The third talk, âMonolith Server Build Optimizationâ, matches the recording of a Miro engineer who said he came back to Miro in March and had maintained a large Gradle monorepo before; the agenda lists Sergey Chernov. The server application is a Spring Boot monolith of roughly a thousand Maven modules in Java and Kotlin, with thousands of integration tests using Testcontainers.
What he reported:
- Gradle prototype rejected. He tried a Gradle migration and found it needed over 10 GB of memory and did not scale well at that module count, so he stayed on Maven and optimised it.
- Smaller wins. Move to the Kotlin 2 compiler, fetch a single commit instead of the full Git history in CI, drop an extension that made CI slower, and keep a separate fast pipeline that builds production artefacts without tests for urgent releases.
- Smarter Maven scheduling. Maven parallelises across independent modules, but a chain of dependent modules builds one by one. By producing the JAR before running tests, downstream modules can start earlier. His time diagram showed a 12-core build of about 21 minutes with idle gaps versus a fuller use of about 7 cores.
- Tests as the bottleneck. Compilation was about 5 percent of the time; tests were the elephant in the room. He split compile and test into separate jobs, used dynamic ports for parallel tests, and built a cache for the Surefire and Failsafe plugins, with inputs such as dependencies, compiled classes and test filter. A change to a moduleâs main code reruns that module and its downstream dependents.
- Results. Pull request build time fell from 60 to 30 minutes at the percentile he showed, and total compute across parallel jobs from eight hours to five. He noted that raw hit rate is misleading, since saved integration-test time matters more than saved unit tests.
The Surefire cache is open source as maven-surefire-cached, published under Apache 2.0.
Breaking up the monolith
The last talk, âBreaking Up the Monolithâ, was introduced by a Miro back-end developer experience engineer who gave his first name as Murat; the agenda lists Murat Ozkan. A second Miro engineer co-presented. The recording is partial and the later part looped, so I only summarise the clear sections:
- The situation. Miro runs hundreds of microservices talking mostly via gRPC, plus a server repository he called the monolith: about 1,000 modules and millions of lines of Java and Kotlin, deployed as 15 to 20 installations, mainly an API server and a board server with different scaling needs.
- Monolith is a spectrum. He argued the problem is not the single repository but the âbig ball of mudâ: unclear boundaries, tight coupling and no documentation. He drew a two-dimensional view, modularity against number of deployment units, and warned about the distributed monolith.
- The plan. Give Maven modules types and rules, for example cross-domain dependencies may only go to a âcontractsâ module with interfaces and no dependencies of its own.
- Metrics. Two were named: a collaborative collisions metric, the share of pull requests to a teamâs code that come from other teams, and ownership fragmentation. Using the code owners file, they found that pull requests from the owning team merged much faster, in some cases three to four times shorter.
My take: measuring pull-request ownership is a cheap way to find where your module boundaries are wrong, before you move any code.
Coming soon
Before the talks, a âComing Soonâ slide listed the next events:
- Thursday 24 July (virtual, free): âUnlock the Power of a High-Performance Java Platformâ
- Monday 11 August (Lunch & Learn): âSimpler Java Build Tools with Object Oriented Programmingâ
- Wednesday 27 August: Amsterdam JUG Meetup at JetBrains
- Friday 19 September: AI4Devs, âNew Developer-Oriented AI Event in Amsterdamâ, with a discount code for JUG members

The âComing Soonâ slide before the evening started.
I wrote up the later AI4Devs event in AI4Devs 2025 in Amsterdam, and a later JUG evening in Amsterdam JUG at ABN AMRO.
