Recent Posts
Archives

Archive for the ‘en-US’ Category

PostHeaderIcon [DotJs2025] Durable Executions for Mortals

Backend’s bedrock—state’s stewardship, asynchrony’s aegis—once consigned coders to queues’ quagmires, yet React’s reactive rite reimagines this realm. Charly Poly, developer marketer at Inngest, advocated durable executions at dotJS 2025, transmuting frontend’s fluency into fault-tolerant flows. A frontend aficionado attuned to async’s arcana, Charly posited workflows as web’s warp: events’ echoes, states’ sagas—sans system’s scutwork.

Charly’s chronicle commenced with React’s renaissance: beyond templates’ tapestry, a triad taming temporality—events’ ingress, data’s domicile, UI’s unison. Backend’s ballad parallels: requests’ reception, persistence’s peril, orchestration’s odyssey. Inngest’s insight: functions as filaments, durable by decree—stepwise sagas, state salved, failures finessed. TypeScript’s temperance: inngest.createFunction({steps: ['ship', 'email']}), waits weaving webhooks—shipment’s vigil, seven-day sentinel.

This tapestry tempers toil: throttling’s thrum, rate’s restraint—web’s whims writ large. Charly contrasted: Temporal’s toils versus Inngest’s intimacy—events’ essence, JS’s jocularity. AI’s affinity: RAG’s relays, agents’ arcs—workflows as warp and weft.

Durable’s dividend: devs’ deliverance—frontend’s flair fortifying backends, sans queues’ quandary.

React’s Reactive Roots

Charly canvassed React’s remit: events’ embrace, fetches’ flux, states’ serenity—templating’s triumph. Backend’s burden: ingress’ influx, persistence’s pang—orchestration’s odyssey.

Inngest’s Immutable Flows

Functions’ filaments: steps’ sequence, waits’ watch—webhooks’ whisper, shipment’s sojourn. TypeScript’s tether: throttling’s tie, AI’s arc—RAG’s relay, agents’ agency.

Links:

PostHeaderIcon [GopherConUK2025] CPU Quota Semantics and Runtime Scheduler Behavior in Containerized Environments

Lecturer

Bill Kennedy is a software engineer, technical trainer, and Managing Partner at Ardan Labs. He has authored multiple technical books on Go programming and serves as a core organizer for developer communities worldwide. His professional work focuses on high-performance backend development, system design, and training software engineering teams on runtime internals and concurrent programming semantics.

Abstract

Deploying managed language runtimes into containerized orchestration frameworks requires a comprehensive understanding of how compute limits interact with application-level scheduling primitives. This article examines the behavior of the Go runtime scheduler when executed under Kubernetes CPU limits. By analyzing thread management, operating system context switching, and the mechanics of Completely Fair Scheduler (CFS) quota enforcement, this study highlights performance degradation scenarios caused by misalignment between thread allocation and container CPU constraints. Furthermore, empirically derived benchmarking demonstrates how adjusting runtime concurrency configurations mitigates kernel-level throttling and improves request throughput in CPU-bound and IO-bound application workloads.

Micro-Architecture, Concurrency, and Context Switching Mechanics

Modern multi-core processors execute operations via clock cycles, where instruction execution frequency depends on pipelined hardware architectures. On a standard processor core running at a 3 GHz clock rate, a single nanosecond corresponds to three clock cycles. Leveraging superscalar execution pipelines, modern hardware can process up to four instructions per clock cycle on average, yielding approximately twelve instructions per nanosecond. Consequently, operational latencies—whether originating from memory access, network round trips, or kernel thread context switches—directly translate into unexecuted instruction cycles.

Operational Event Approximate Duration Lost Instruction Opportunities
OS Thread Context Switch 1,000 ns (1 µs) ~12,000 instructions
Datacenter Network Round Trip 500,000 ns (0.5 ms) ~6,000,000 instructions
Go Routine Context Switch 200 ns ~2,400 instructions

In system software, workloads are categorized as either CPU-bound or IO-bound. CPU-bound tasks execute uninterrupted mathematical or logical operations, utilizing their full operating system time slice. Under CPU-bound conditions, context switches incur overhead that degrades throughput unless application thread counts strictly match available physical cores. Conversely, IO-bound workloads frequently transition threads into blocked or waiting states due to asynchronous network calls or file interactions.

The Go runtime abstracts operating system (OS) threads through an M:N scheduler, mapping M goroutines (application-level lightweight threads) onto N OS threads managed across logical processors known as P structures. Physical CPU cores are abstracted into these P units, which hold local run queues for goroutines. The Go scheduler operates as a work-stealing system: idle P structures steal runnable goroutines from other local queues or a global run queue.

+-----------------------------------------------+
|                 OS Kernel                     |
|  [Core 0]    [Core 1]    [Core 2]    [Core 3] |
+-----------------------------------------------+
       ^          ^           ^           ^
       |          |           |           |
    [  M  ]    [  M  ]     [  M  ]     [  M  ]
       |          |           |           |
    [  P  ]    [  P  ]     [  P  ]     [  P  ]
    /     \      ...         ...         ...
 [ G ]   [ G ]

To maximize thread utilization, asynchronous system calls (such as network operations) are handled via a dedicated network poller thread. When a goroutine initiates a network read, the runtime detaches the goroutine from its current M thread and registers it with the network poller. This frees the underlying M thread to immediately execute other goroutines assigned to that logical P processor. Synchronous operations, such as blocking file system IO, force the runtime to decouple the blocking M thread from its assigned P structure and allocate or unpark a separate OS thread to keep the P processor active.

Through this abstraction, the Go runtime transforms application-level IO-bound tasks into CPU-bound operational streams from the operating system’s perspective. The OS kernel observes saturated worker threads (M), allowing them to consume allocated time slices efficiently without premature thread parking.

Kubernetes Completely Fair Scheduler (CFS) Quota Semantics

Kubernetes enforces compute resource limits using Linux control groups (cgroups) via the Completely Fair Scheduler (CFS) quota system. A CPU resource limit specified in millicores (such as 250m) translates into a time-based allocation per enforcement period. By default, the Linux kernel CFS operates on a 100-millisecond period.

Allocated Time Formula:
Allocated Time = CFS Period * (Millicores / 1000)

For an allocation of 250m across a 100 ms period, the container receives exactly 25 ms of cumulative execution time:

Allocated Time = 100 ms * (250 / 1000) = 25 ms

Crucially, the Linux CFS tracks CPU quota consumption cumulatively across all running OS threads within the container’s thread group. If an application spawns 16 threads that execute concurrently on a multi-core host system, each thread consumes physical core time simultaneously.

Quota Exhaustion Rate:
Quota Exhaustion Rate = Number of Threads * Elapsed Time

With 16 active OS threads, a 25 ms CPU quota is depleted in less than 2 ms of real time:

Exhaustion Time = 25 ms / 16 = 1.5625 ms

Once the total execution time across all threads reaches the 25 ms ceiling, the kernel CFS throttles the entire container. The container processes remain paused until the 100 ms cycle resets, resulting in severe latency spikes and degraded service throughput.

Architectural Misalignment: Go Max Procs in Container Runtimes

By default, the Go runtime initializes the number of logical processors (P) via the GOMAXPROCS variable based on system calls that query host core availability. In standard Kubernetes pod deployments without explicit runtime tuning, the runtime inspects the host node rather than container cgroup boundaries.

If a pod configured with a 250m limit is scheduled on a 16-core physical node, GOMAXPROCS defaults to 16. The runtime creates 16 logical P processors and corresponding OS threads (M).

Container Configuration: CPU Limit = 250m (25ms per 100ms cycle)
Host Infrastructure: 16 Physical Cores
Default Go Runtime Behavior: GOMAXPROCS = 16

+-------------------------------------------------------+
| 16 OS Threads (M) Executing Simultaneously           |
| [M1] [M2] [M3] [M4] [M5] [M6] ... [M16]               |
+-------------------------------------------------------+
                           |
                           v
    Consumes 25ms Quota in ~1.56ms of Real Time
                           |
                           v
+-------------------------------------------------------+
| Kernel CFS Throttles Container for Remaining ~98.4ms  |
+-------------------------------------------------------+

When incoming requests hit the container, all 16 worker threads wake up to process goroutines. The cumulative CPU time consumed by these 16 concurrent threads exhausts the 25 ms cgroup quota almost instantly. The application spends the vast majority of every 100 ms enforcement window in a kernel-throttled state.

To resolve this misalignment, the application runtime must match its logical thread capacity to its cgroup quota boundaries. Setting GOMAXPROCS=1 forces the Go scheduler to utilize a single logical P processor and one primary operating thread, executing sequential instructions over the full 25 ms window without premature multi-threaded quota depletion.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sales-service
spec:
  template:
    spec:
      containers:
      - name: service
        image: sales-service:1.0
        env:
        - name: GOMAXPROCS
          valueFrom:
            resourceFieldRef:
              resource: limits.cpu
        resources:
          limits:
            cpu: "250m"

In Go deployments, setting GOMAXPROCS via container environment variables applies a mathematical ceiling function to convert fractional core limits into discrete thread bounds.

Experimental Evaluation and System Optimization

Empirical performance tests were conducted on a Kubernetes cluster managed via kind hosted on an 16-core machine. The microservice stack comprised an HTTP API service backed by a PostgreSQL database. Load testing was executed using automated benchmark tools transmitting synthetic HTTP workloads.

Test Configuration A: Default Core Allocation

  • CPU Limit: 250m (25 ms per 100 ms)
  • Host Cores Detected: 16
  • GOMAXPROCS: 16 (Default)

Test Configuration B: Matched Runtime Constraints

  • CPU Limit: 250m (25 ms per 100 ms)
  • Host Cores Detected: 16
  • GOMAXPROCS: 1 (Explicitly configured)

Measured Experimental Results

Metric Config A (GOMAXPROCS=16) Config B (GOMAXPROCS=1) Performance Impact
Throughput ~126 req/sec ~2,746 req/sec ~21.7x Increase
P99 Latency ~200 ms ~3.6 ms ~98.2% Reduction

Constraining the runtime thread count to align with container limits produced a 21-fold throughput increase while eliminating excessive tail latency caused by kernel CFS throttling.

Cascading Latency and Upstream Service Dependencies

In distributed microservice topologies, runtime throttling can cascade across service boundaries. During secondary experimentation, an authentication service dependency (auth-service) was assigned a restricted CPU limit (100m).

Even when the primary edge service (sales-service) was provisioned with unrestricted CPU allocations, overall request throughput dropped to baseline throttled levels. Blocking latencies introduced by the throttled upstream dependency bottlenecked the unconstrained downstream service. Diagnosing performance anomalies requires evaluating total system execution graphs rather than isolating individual application metrics.

Links:

PostHeaderIcon [SpringIO2025] Real-World AI Patterns with Spring AI and Vaadin by Marcus Hellberg / Thomas Vitale

Lecturer

Marcus Hellberg is the Vice President of AI Research at Vaadin, a company specializing in tools for Java developers to build web applications. As a Java Champion with nearly 20 years of experience in Java and web development, he focuses on integrating AI capabilities into Java ecosystems. Thomas Vitale is a software engineer at Systematic, a Danish software company, with expertise in cloud-native solutions, Java, and AI. He is the author of “Cloud Native Spring in Action” and an upcoming book on developer experience on Kubernetes, and serves as a CNCF Ambassador.

Abstract

This article examines practical patterns for incorporating artificial intelligence into Java applications using Spring AI and Vaadin, transitioning from experimental to production-ready implementations. It analyzes techniques for memory management, guardrails, multimodality, retrieval-augmented generation, tool calling, and agents, with implications for security, user experience, and system integration. Insights emphasize robust, observable AI workflows in on-premises or cloud environments.

Memory Management and Streaming in AI Interactions

Integrating large language models (LLMs) into applications requires addressing their stateless nature, where each interaction lacks inherent context from prior exchanges. Spring AI provides advisors—interceptor-like mechanisms—to augment prompts with conversation history, enabling short-term memory. For instance, a MessageChatMemoryAdvisor retains the last N messages, ensuring continuity without manual tracking.

This pattern enhances user interactions in chat-based interfaces, built here with Vaadin’s component model for server-side Java UIs. A vertical layout hosts message lists and inputs, injecting a ChatClientBuilder to construct clients with advisors. Basic interactions involve prompting the model and appending responses, but for realism, streaming via reactive fluxes improves responsiveness, subscribing to token streams and updating UI progressively.

Code illustration:

ChatClient chatClient = builder.build();
messageInput.addSubmitListener(submitEvent -> {
    String message = submitEvent.getMessage();
    MessageItem userItem = messageList.addMessage("You", message);
    chatClient.stream(new Prompt(message))
        .subscribe(response -> {
            userItem.append(response.getResult().getOutput().getContent());
        });
});

Streaming suits verbose responses, reducing perceived latency, while observability integrations (e.g., OpenTelemetry) trace interactions for debugging nondeterministic behaviors.

Guardrails for Security and Validation

AI workflows must mitigate risks like sensitive data leaks or invalid outputs. Input guardrails intercept prompts, using on-premises models to check for compliance with policies, blocking unauthorized queries (e.g., personal information). Output guardrails validate responses, reprompting for corrections if deserialization fails.

Advisors enable this: a default advisor with a local chat model filters inputs/outputs. For example, querying an address might be blocked if flagged, preventing cloud exposure. This ensures determinism in structured outputs, converting unstructured text to Java objects via JSON instructions.

Implications include privacy preservation in regulated sectors and integration with Spring Security for role-based tool access.

Multimodality and Retrieval-Augmented Generation

LLMs extend beyond text through multimodality, processing images, audio, or videos. Spring AI’s entity methods augment prompts for structured extraction, e.g., parsing attendee details from images into tables for programmatic use.

Retrieval-augmented generation (RAG) combats hallucinations by embedding external data as vectors in stores like PostgreSQL. A RetrievalAugmentationAdvisor retrieves relevant documents via similarity search, augmenting prompts. Customizations allow empty contexts for fallback to model knowledge.

Example:

VectorStore vectorStore = // PostgreSQL vector store
DocumentRetriever retriever = new VectorStoreDocumentRetriever(vectorStore);
RetrievalAugmentationAdvisor advisor = RetrievalAugmentationAdvisor.builder()
    .documentRetriever(retriever)
    .queryAugmentor(QueryAugmentor.contextual().allowEmptyContext(true))
    .build();

This pattern grounds responses in proprietary data, with thresholds controlling retrieval scope.

Tool Calling, Agents, and Dynamic Integrations

Tool calling empowers LLMs as agents, invoking external functions for tasks like database queries. Annotations describe tools, passed to clients for dynamic selection. For products, a service might expose query/update methods:

@Tool(description = "Fetch products from database")
public List<Product> getProducts(@P(description = "Category filter") String category) {
    // Database query
}

Agents orchestrate tools, potentially via Model Context Protocol for external services. Demonstrations include theme generation from screenshots, editing CSS via file system tools, highlighting nondeterminism and the need for safeguards.

In conclusion, these patterns enable production AI, emphasizing modularity, security, and observability for robust Java applications.

Links:

PostHeaderIcon [DevoxxBE2025] Live Coding The Hive: Building a Microservices-Ready Modular Monolith

Lecturer

Thomas Pierrain is Vice President of Engineering at Agicap, a financial management platform, where he applies domain-driven design to build scalable systems. Julien Topcu is Vice President of Technology at SHODO Group, a consultancy focused on socio-technical coaching and architecture, with expertise in helping teams implement domain-driven practices.

Abstract

This analysis investigates the Hive pattern, an architectural approach for creating modular monoliths that support easy evolution to microservices. It identifies key ideas like vertical slicing and port-adapter boundaries, set against the backdrop of microservices pitfalls. Highlighting a live-refactored time-travel system, it details methods for domain alignment, encapsulation, and simulated distributed communication. Consequences for system flexibility, debt management, and scalability are evaluated, providing insights into resilient designs for existing and new developments.

Emergence from Microservices Challenges

Over a decade, the shift to microservices has often resulted in distributed messes, worse than the monoliths they replaced due to added complexity in coordination and deployment. The modular monolith concept arises as a remedy, but risks tight coupling if not properly segmented. The Hive addresses this by separating design from deployment, following “construct once, deploy flexibly.”

In the live example, a time-machine’s control system—handling energy, navigation, and diagnostics—crashes due to fragility, landing in the 1980s. Diagnostics reveal a muddled structure with high resource use, mirroring legacy systems burdened by modeling debt—the buildup of imprecise domain models hindering change.

The pattern’s innovation lies in fractal composability: modules as hexagons can nest or extract as services. This enables scaling in (sub-modules) or out (microservices), adapting to needs like independent deployment for high-load components.

Essential Tenets of the Hive

Vertical slicing packs modules with all necessities—logic, storage, interfaces—for self-sufficiency, avoiding shared layers’ dependencies. In the demo, the energy module includes its database, isolating it from navigation.

Port-adapter encapsulation defines interaction points: inbound for incoming, outbound for outgoing. Adapters translate, eliminating direct links. The navigation’s energy request port uses an adapter to call the energy’s provision port, preventing tangles.

Inter-module talks mimic microservices sans networks, using in-process events. This readies for distribution: swapping adapters for remote calls extracts modules seamlessly. The example routes via a bus, allowing monolith operation with distributed readiness.

These tenets create a supple framework, resilient to evolution. The fractal aspect allows infinite composition, as shown by nesting diagnostics within navigation.

Refactoring Methodology and Practical Steps

The session starts with a monolithic system showing instability: overused resources cause anomalies. AI schemas expose entanglements, guiding domain identification—energy, time circuits, AI.

Modules reorganize: each hexagon sliced vertically with dedicated storage. Code moves via IDE tools, databases split to prevent sharing. Energy gains PostgreSQL, queried through adapters.

Communication restructures: ports define contracts, adapters implement. Navigation’s outbound energy port adapts to energy’s inbound, using events for asynchrony.

Extraction demonstrates: energy becomes a microservice by changing adapters to network-based, deploying separately without core changes. Tests modularize similarly, using mocks for isolation.

This step-by-step approach handles brownfields incrementally, using tools for safe restructuring.

Resilience, Scalability, and Debt Mitigation

Hive’s boundaries enhance resilience: changes localize, as energy tweaks affect only its hexagon. This curbs debt, allowing independent domain refinement.

Scalability is fractal: inward nesting subdivides, outward extraction distributes. Networkless talks ease transitions, minimizing rewrites.

Versus monoliths’ coupling or microservices’ prematurity, Hive balances, domain-focused for “right-sized” architectures. Challenges: upfront refactoring, boundary discipline.

Development Ramifications and Adoption

Hive promotes adaptive designs for changing businesses. Starting modular prevents debt in new projects; modernizes legacies via paths shown.

Wider effects: better sustainment, lower costs through contained modules. As hype fades, Hive provides hybrids, emphasizing appropriate sizing.

Future: broader use in frameworks, tools for pattern enforcement.

In overview, Hive exemplifies composable resilience, merging monolith unity with microservices adaptability.

Links:

  • Lecture video: https://www.youtube.com/watch?v=VKcRNtj0tzc
  • Thomas Pierrain on LinkedIn: https://fr.linkedin.com/in/thomas-p-0664769
  • Thomas Pierrain on Twitter/X: https://twitter.com/tpierrain
  • Julien Topcu on LinkedIn: https://fr.linkedin.com/in/julien-top%25C3%25A7u
  • Agicap website: https://agicap.com/
  • SHODO Group website: https://shodo.io/

PostHeaderIcon From JMS and Message Queues to Kafka Streams: Why Kafka Had to Be Invented

For decades, enterprise systems relied on message queues and JMS-based brokers to decouple applications and ensure reliable communication. Technologies such as IBM MQ, ActiveMQ, and later RabbitMQ solved an important problem: how to move messages safely from one system to another without tight coupling.

However, as systems grew larger, more distributed, and more data-driven, the limitations of this model became increasingly apparent. Kafka — and later Kafka Streams — did not emerge because JMS and MQ were poorly designed. They emerged because they were designed for a different era and a different class of problems.

What JMS and MQ Were Designed to Do

Traditional message brokers focus on delivery. A producer sends a message, the broker stores it temporarily, and a consumer receives it. Once the message is acknowledged, it is typically removed. The broker’s primary responsibility is to guarantee that messages are delivered reliably and, in some cases, transactionally.

This model works very well for command-style interactions such as order submission, workflow orchestration, and request-driven integration between systems. Messages are transient by design, consumers are expected to be online, and the system’s success is measured by how quickly and reliably messages move through it.

For many years, this was sufficient.

The Problems That Started to Appear

As companies began operating at internet scale, the assumptions underlying JMS and MQ started to break down. Data volumes increased dramatically, and systems needed to handle not thousands, but millions of events per second. Message brokers that tracked delivery state per consumer became bottlenecks, both technically and operationally.

More importantly, the nature of the data changed. Events were no longer just instructions to be executed and discarded. They became facts: user actions, transactions, logs, metrics, and behavioral signals that needed to be stored, analyzed, and revisited.

With JMS and MQ, once a message was consumed, it was gone. Reprocessing required complex duplication strategies or external storage. Adding a new consumer meant replaying data manually, if it was even possible. The broker was optimized for delivery, not for history.

At the same time, architectures became more decoupled. Multiple teams wanted to consume the same data independently, at their own pace, and for different purposes. In a traditional queue-based system, this required copying messages or creating parallel queues, increasing cost and complexity.

These pressures revealed a fundamental mismatch between what message queues were built for and what modern systems required.

The Conceptual Shift That Led to Kafka

Kafka was created to answer a different question. Instead of asking how to deliver messages efficiently, its designers asked how to store events reliably at scale and allow many consumers to read them independently.

The key idea was deceptively simple: treat data as an append-only log. Producers write events to a log, and consumers read from that log at their own pace. Events are not deleted when consumed. They are retained for a configurable period, or even indefinitely.

In this model, the broker no longer tracks who consumed what. Each consumer keeps track of its own position. This small change eliminates a major scalability bottleneck and makes replay a natural operation rather than an exceptional one.

Kafka’s architecture reflects this shift. It is disk-first rather than memory-first, optimized for sequential writes and reads. It scales horizontally through partitioning. It treats durability and throughput as complementary goals rather than trade-offs.

Kafka was not created to replace message queues; it was created to solve problems message queues were never meant to solve.

From Transport to Platform: Why Kafka Streams Exists

Kafka alone provides storage and distribution of events, but it does not process them. Early Kafka users still needed external systems to transform, aggregate, and analyze data flowing through Kafka.

Kafka Streams was created to close this gap.

Instead of introducing another centralized processing cluster, Kafka Streams embeds stream processing directly into applications. This is a deliberate contrast with both JMS consumers and large external processing frameworks.

In a JMS-based system, consumers typically process messages one at a time, often statelessly, and rely on external databases for aggregation and state. Rebuilding state after a failure is complex and error-prone.

Kafka Streams, by contrast, assumes that stateful processing is normal. It provides abstractions for event streams and for state that evolves over time. It stores state locally for performance and backs it up to Kafka so it can be restored automatically. Processing logic, state, and data history are all aligned around the same event log.

This approach turns Kafka from a passive transport layer into an active data platform.

What Kafka and Kafka Streams Do Differently

The fundamental difference between JMS/MQ and Kafka is not syntax or APIs, but philosophy.

Message queues focus on messages as transient instructions. Kafka focuses on events as durable facts. Message queues optimize for delivery guarantees. Kafka optimizes for scalability, retention, and replay. Message queues treat consumers as part of the broker’s responsibility. Kafka treats consumers as independent actors.

Kafka Streams builds on this by assuming that computation belongs close to the data. Instead of shipping data to a processing engine, it ships processing logic to where the data already is. This inversion dramatically simplifies architectures while increasing reliability.

Why Someone “Woke Up and Created Kafka”

Kafka was born out of necessity. At companies like LinkedIn, existing messaging systems could not handle the volume, variety, and longevity of data they were producing. They needed a system that could ingest everything, store it reliably, and make it available to many consumers without coordination.

Kafka Streams followed naturally. Once data became durable and replayable, processing it in a stateless, fire-and-forget manner was no longer sufficient. Systems needed to compute continuously, maintain state, and recover automatically — all while remaining simple to operate.

Kafka and Kafka Streams are the result of rethinking messaging from first principles, in response to scale, data-driven architectures, and the need to treat events as first-class citizens.

Conclusion

JMS and traditional message queues remain excellent tools for command-based integration and transactional workflows. Kafka was not designed to replace them, but to address a different category of problems.

Kafka introduced the idea of a distributed, durable event log as the backbone of modern systems. Kafka Streams extended that idea by embedding real-time pro

PostHeaderIcon [PyConUS2025] Lightning Talks Sunday Morning: Packaging Practicalities, Documentation Delight, Labor Solidarity, and Global Community Horizons

Lecturer

The final lightning-talk session of the conference was hosted by community organizers who again managed a dense sequence of short presentations. Speakers included Illirik Smirnov on international telephone-number handling; Evan Kohilas on the evolving signature of re.sub; Adam Silkey on embeddable Python distributions for Windows; Jonathan Daniel on accelerating Docker builds with uv; Takanori Suzuki on cat-emoji Sphinx extensions; Jing Cao on lessons from a technology-guild strike; Michael McCaffrey on strategies for long-term goal pursuit under ADHD and anxiety; Joongi Kim reflecting on a decade of PyCon Korea; Dave Peck surveying t-strings; and Sheena O’Connell surveying the state of Python communities across Africa. The session concluded with an extended series of regional-conference announcements, underscoring the geographic breadth of the language’s user base.

Abstract

Sunday morning’s lightning talks addressed concrete packaging and tooling improvements, documentation aesthetics, workplace organizing, personal cognitive strategies, long-term conference stewardship, emerging language features, and the vitality of African Python communities, followed by a rapid tour of forthcoming regional events on five continents. The program balanced immediate technical utility with longer-horizon reflections on labor, accessibility, and global participation.

Packaging, Tooling, and Documentation Enhancements

Illirik Smirnov examined the surprisingly non-local nature of telephone numbers. Because the same digit sequence may be valid under different national numbering plans, storage and validation require an explicit regional context. The phonenumbers library, implementing the ITU E.164 standard, accepts free-text input plus a default region and returns canonical international or national formats. Smirnov recommended pairing a country selector with an unrestricted text field, thereby avoiding brittle client-side formatting while still guaranteeing a normalized database representation. Additional nuance for the North American Numbering Plan—where the shared country code +1 encompasses multiple nations—was noted as a further source of billing and routing surprises.

Evan Kohilas analyzed the deprecation, beginning in Python 3.13, of positional arguments for the optional count and flags parameters of re.sub. The change eliminates a class of silent errors in which a flags value is inadvertently interpreted as a substitution limit. Kohilas used the episode to advocate broader adoption of keyword arguments for self-documenting, order-independent, and refactor-safe call sites. Linter rules that enforce or auto-convert to keyword style were presented as pragmatic mechanisms for reducing human error without requiring every function signature to begin with a bare *.

Adam Silkey demonstrated a single-file batch script that unpacks an embeddable CPython distribution on a clean Windows installation and immediately executes a Python program. By base64-encoding the official embeddable zip and extracting it at runtime, the technique sidesteps traditional installer friction and supplies a reproducible, offline-capable Python environment. An open-space invitation promised deeper technical exposition.

Jonathan Daniel reported production experience replacing pip install -r requirements.txt with uv pip install inside Docker builds. Generation of a fully locked requirements file from an unpinned source list, followed by installation via uv, yielded an approximately 70 percent reduction in build time and an unexpected 30 percent reduction in image size—the latter attributable to uv’s default omission of bytecode compilation. Subsequent addition of explicit bytecode generation restored start-up performance while preserving most of the size advantage. The talk illustrated both the measurable impact of modern packaging tools and the value of investigating anomalous metrics.

Takanori Suzuki introduced sphinx-neochang, a Sphinx extension that embeds a large set of cat emojis designed by the Japanese illustrator Shikama-san. After installation and a one-line configuration change, authors may insert named emojis via a simple role; the same mechanism works inside Sphinx-RevealJS slide decks. Size, rotation, and flip parameters further increase expressive range. The project converts a popular chat-culture artifact into first-class documentation and presentation assets, demonstrating the playful side of the documentation toolchain.

Labor, Cognition, and Long-Term Stewardship

Jing Cao reflected on participation in the New York Times Tech Guild strike. The experience clarified the concrete mechanisms—collective bargaining, mutual aid, and public narrative—through which software workers can negotiate working conditions. Cao emphasized that solidarity across job categories and the willingness to accept short-term disruption proved essential to securing longer-term gains, offering a rare workplace-organizing perspective inside a conference program more often focused on technical rather than industrial relations.

Michael McCaffrey addressed the intersection of ADHD, anxiety, and sustained technical work. Strategies for breaking long-horizon goals into externally visible milestones, externalizing memory into reliable systems, and cultivating compassionate accountability structures were outlined. The talk normalized the cognitive diversity present in the community and supplied pragmatic tactics rather than motivational platitudes.

Joongi Kim surveyed ten years of involvement with PyCon Korea. The narrative traced the conference’s growth, the successive organizational challenges of venue, sponsorship, and volunteer continuity, and the personal satisfaction of watching a regional community mature. The retrospective illustrated the multi-year commitment required to sustain a successful national event.

Language Evolution and Global Horizons

Dave Peck provided a rapid introduction to t-strings, an emerging string-processing facility under discussion for future Python versions. The feature aims to supply safer and more expressive interpolation and templating primitives; Peck’s whirlwind tour highlighted both syntactic possibilities and open design questions.

Sheena O’Connell closed the formal talks with a survey of Python activity across the African continent. Communities in numerous countries exhibit high technical skill, strong mutual support, and creative problem-solving under resource constraints. O’Connell encouraged attendees to follow African conference streams, attend in person when possible, organize watch parties, and consider sponsorship or mentorship relationships. The talk countered residual geographic stereotypes and positioned African Pythonistas as both peers and potential collaborators.

The remainder of the session consisted of rapid-fire announcements of forthcoming regional conferences: PyLadTAm in Costa Rica, EuroPython in Prague, PyCon Australia and New Zealand, EuroSciPy in Kraków, the inaugural PyCon Greece, North Bay Python, PyCon Korea, PyCon Malaysia, PyCon Indonesia, PyOhio, PyCon UK, DjangoCon US, PyCon Taiwan, PyCon JP in Hiroshima, PyCascades in Vancouver, PyBay, PyCon Finland, PyTexas, PyCon Singapore, SciPy in Tacoma, PyCon Portugal, Python Brasil and its regional satellites, PyBeach, PyCon Africa in Johannesburg, a Python Asia online charity event, and PyLadies Con. Each announcement underscored the continued geographic expansion of the language’s conference ecosystem and the reciprocal relationships that link local organizers to the global community.

Taken together, the Sunday morning program moved from immediate packaging and documentation improvements through questions of labor and personal cognition to a panoramic view of the worldwide Python landscape, closing the conference’s lightning-talk sequence on a note of both technical practicality and expansive solidarity.

Links:

PostHeaderIcon [DotJs2024] Encrypt All Transports

In the shadowed corridors of digital discourse, where data streams pulse like vital arteries, lurks the imperative to cloak communications in unbreakable veils. Eleanor McHugh, a freelance reality consultant and anonymity architect with three decades spanning avionics to blockchain, issued this mandate at dotJS 2024. Ellie, co-founder of Innovative Identity Solutions, decried surveillance’s specter—from Lenovo’s BIOS interlopers to AI’s voracious scans—positing developers as privacy’s vanguard. Her whirlwind primer: wield WebSockets, RSA, AES in Node and browser crucibles, forging transports impervious to prying eyes.

Ellie’s ire ignited with 2015’s scandals: adware proxies hijacking HTTPS, unmasking “secure” flows for monetization. Today’s AI fervor—Facebook, Microsoft, Apple coveting content—echoes, demanding defiance. Privacy’s etymology—privity’s pact, NDA’s shroud—binds us; yet CTOs crave visibility, debugging APIs dissecting deeds at dawn’s witching hour. Ellie indicted: we, the coders, perpetuate panopticons, outsourcing souls to Albanian bunkers or quakesafe vaults. Reclamation resides in crypto’s toolkit: symmetric ciphers scrambling payloads, asymmetric duos authenticating origins, signatures vouching veracity, zero-knowledge veiling proofs.

Ellie’s arsenal gleams in GitHub’s forge: WebSockets for bidirectional brooks, RSA’s key pairs partitioning public probes from private vaults, AES randomizing streams into gibberish. Node’s crypto module, browser’s SubtleCrypto—both tame these titans. A vignette: socket spawns, keys exchanged via Diffie-Hellman ephemera, payloads AES-encrypted, RSA-signed—interception yields noise, replay thwarted by nonces. Zero-knowledge crowns: prove solvency sans balances, age sans birthdates—zk-SNARKs succinct, verifiable.

Ellie’s entreaty: tinker this trove, erect enclosures where client secrets elude server spies. As liveness biometrics and encrypted enclaves evolve, her free chapter beckons—crypto sans cost, privacy paramount. In software’s void, we architect anonymity; shirk not this solemnity.

Crypto Primitives in Play

Ellie enumerated: AES symmetrizes speed, RSA asymmetrizes trust—public encrypts, private decrypts. Signatures seal integrity; zk proofs affirm attributes incognito. WebSockets underpin, channels churning ciphered chatter—Node’s forge, browser’s bastion.

Defending Against Digital Dragnets

From BIOS betrayals to AI appetites, Ellie’s exposé exhorted: encrypt endpoints, anonymize identities. Her slides loop—3:30 eternities—urging uptake: GitHub’s gallery, SlideShare’s scrolls. Consultations await; privacy’s perimeter, we patrol.

Links:

PostHeaderIcon [GoogleIO2024] What’s New in Flutter: Cross-Platform Innovations and Performance Boosts

Flutter’s pillars—portability, performance, and openness—drive its evolution. Kevin Moore and John Ryan highlighted five key updates, from AI integrations to web assembly support, empowering developers to create seamless experiences across devices.

Portability Across Platforms with Gemini API

Kevin stressed Flutter’s code-sharing efficiency, achieving 97% reuse in Google’s apps. The Gemini API integration via Google AI Dart SDK enables generative features, like image-to-text in apps such as Bricket, which identifies Lego bricks for model suggestions.

Global Gamers Challenge with Global Citizen showcased Flutter’s gaming potential, with winners like “Save the Lot” addressing environmental issues. Resources for game development, including Casual Games Toolkit, facilitate cross-platform builds.

Performance Enhancements with Impeller and Macros

John introduced Impeller on Android, Flutter’s rendering engine, reducing jank through precompiled shaders. Benchmarks show up to 50% frame time improvements, enhancing experiences on mid-range devices.

Dart macros, in experimental preview, automate boilerplate code for tasks like JSON serialization, boosting developer productivity without runtime overhead.

Web Optimization Through Web Assembly

Web Assembly compilation in Flutter 3.22 doubles performance, with up to 4x gains in demanding frames. This consistency minimizes jank, enabling richer web apps.

Collaborations with browser teams ensure broad compatibility, aligning with Flutter’s open ethos.

These 2024 updates solidify Flutter’s role in efficient, high-performance app development.

Links:

PostHeaderIcon [DevoxxGR2025] Understanding Flow in Software Development

James Lewis, a ThoughtWorks consultant, delivered a 41-minute talk at Devoxx Greece 2025, exploring how work flows through software development, drawing on information theory and complexity science.

The Nature of Work as Information

Lewis framed software development as transforming “stuff” into more valuable outputs, akin to enterprise workflows before computers. Work, invisible as information, flows through value streams—from ideas to production code. However, invisibility causes issues like unnoticed backlogs or undeployed code, acting as costly inventory. Lewis cited Don Reinertsen’s Principles of Product Development Flow, emphasizing that untested or undeployed code represents lost revenue, unlike visible factory inventory, which signals inefficiencies immediately.

Visualizing Value Streams

Using a value stream map, Lewis illustrated a typical development cycle: three days for coding, ten days waiting for testing, and 30 days for deployment, totaling 47 days of lead time, with 42 days as idle inventory. Wait times stem from coordination (teams waiting on others), scheduling (e.g., architecture reviews), and queues (backlogs). Shared test environments exacerbate delays, costing more than provisioning new ones. Lewis advocated mapping workflows to expose economic losses, making a case for faster delivery to stakeholders.

Reducing Batch Sizes for Flow

Lewis emphasized reducing batch sizes to improve flow, a principle rooted in queuing theory. Smaller batches, like deploying twice as often, halve wait times, enabling faster revenue generation. Using agent-based models, he simulated agile (single-piece flow) versus waterfall (100% batch) teams, showing agile teams deliver value faster. Limiting work-in-progress and controlling queue sizes prevent congestion collapse, ensuring smoother, more predictable workflows.

Links

PostHeaderIcon [AWSReInforce2025] Secure and scalable customer IAM with Cognito: Wiz’s success story (IAM221)

Lecturer

Rahul Sharma serves as Principal Product Manager for Amazon Cognito at AWS, driving the roadmap for customer identity and access management (CIAM) at global scale. Alex Vorte functions as Field CTO for Login and RBAC at Wiz, leading identity transformation initiatives that support FedRAMP authorization and enterprise compliance.

Abstract

The case study examines Wiz’s migration of 100,000+ identities to Amazon Cognito, achieving FedRAMP High authorization, 99.9% availability, and 70% cost reduction. It establishes best practices for CIAM modernization—migration strategies, machine identity integration, and SLA alignment—that balance security, scalability, and user experience.

Migration Strategy and Execution Framework

Wiz executed a phased migration across three cohorts:

  1. Pilot (0-10% users): Parallel authentication flows
  2. Canary (10-50%): Gradual traffic shift with feature flags
  3. Cutover (50-100%): Automated bulk migration
\# Bulk migration pseudocode
for user in legacy_db.batch(1000):
    cognito.admin_create_user(
        Username=user.email,
        TemporaryPassword=generate_secure_temp(),
        UserAttributes=user.profile
    )
    trigger_password_reset_email(user)

The platform processed 100,000 identities in under one year, with zero downtime during cutover.

Security and Compliance Architecture

FedRAMP High requirements drove design decisions:

  • Encryption: KMS customer-managed keys for data at rest
  • Network: VPC-private user pools with AWS PrivateLink
  • Audit: CloudTrail integration for all admin actions
  • MFA: Mandatory WebAuthn with hardware key support

Cognito’s built-in compliance (SOC, PCI, ISO) eliminated third-party audit burden.

Scalability and Availability Engineering

Architecture supports 10,000 RPS authentication:

Global Accelerator → CloudFront → Cognito (multi-AZ)
                          ↓
                     Lambda@Edge for custom auth

SLA achievement:
– RTO: < 4 hours via cross-region replication
– RPO: < 1 minute with continuous backups
– Availability: 99.9% through health checks and auto-scaling

Machine Identity Integration

Beyond human users, Cognito manages:

  • Service accounts: OAuth2 client credentials flow
  • CI/CD pipelines: Federated tokens via OIDC
  • IoT devices: Custom authenticator with X.509 certificates
// CI/CD token acquisition
CognitoIdentityProvider client = ...
InitiateAuthRequest request = new InitiateAuthRequest()
    .withAuthFlow(AuthFlowType.CLIENT_CREDENTIALS)
    .withClientId(PIPELINE_CLIENT_ID);

This unified approach reduced identity sprawl by 60%.

Cost Optimization Outcomes

Migration yielded 70% reduction through:

  • Elimination of legacy IdP licensing
  • Pay-per-monthly-active-user pricing
  • Removal of custom auth infrastructure
  • Automated user lifecycle management

Best Practices for CIAM Modernization

  1. Choose migration strategy by risk tolerance: parallel runs for zero-downtime
  2. Leverage Cognito migration APIs: bulk import with password hash preservation
  3. Implement progressive enhancement: start with email/password, add MFA/social later
  4. Align with product roadmap: design partner relationship for feature priority

Conclusion: CIAM as Strategic Enabler

Wiz’s transformation demonstrates that modern CIAM need not compromise between security, scale, and cost. Amazon Cognito provides the managed substrate that absorbs authentication complexity, enabling security teams to focus on policy and governance rather than infrastructure. The migration framework—phased execution, machine identity integration, and SLA engineering—offers a repeatable pattern for enterprises undergoing digital transformation.

Links: