Recent Posts
Archives

PostHeaderIcon [AWSReInventPartnerSessions2024] Usage

acc = Account(1000)
acc.transaction(500)
print(acc.balance) # 1500
“`

This highlights transformation techniques preserving logic.

Integration of Generative AI and Evaluation

Generative AI streamlines documentation and insights, though not yet fully automating conversions. It complements deterministic tools that have processed billions of code lines, ensuring reliability.

Evaluation against baselines confirms improvements, with AI aiding in artifact generation for better stakeholder understanding.

Implications for Future Modernization Patterns

The project enables application sunsetting and varied post-migration strategies, enhancing agility. AI’s role in testing and analysis de-risks efforts, improving outcomes.

In conclusion, this case demonstrates how combining executive support, proven methodologies, and AI accelerates modernization, positioning organizations for innovation and reduced risks.

Links:

PostHeaderIcon [DevoxxUK2025] Kotlin: The New and Noteworthy

Anton Arhipov, a developer advocate from JetBrains, captivated the DevoxxUK2025 audience with an overview of Kotlin’s recent advancements and future roadmap. Focusing on Kotlin 2.0’s K2 compiler and upcoming features like guard conditions, context parameters, rich errors, and name-based destructuring, Anton highlighted how Kotlin balances conciseness, safety, and expressiveness. His interactive talk, enriched with personal anecdotes and live demos, underscored Kotlin’s evolution as a versatile, multi-platform language that empowers developers to write robust, readable code.

Kotlin 2.0 and the K2 Compiler

Anton introduced Kotlin 2.0, released nearly a year ago, emphasizing the K2 compiler’s new front-end intermediate representation (FIR) and control flow engine. K2 improved compilation performance by 40% in IntelliJ IDEA Ultimate, fixed numerous small bugs, and provided a scalable foundation for future features. By desugaring complex constructs (e.g., if to when expressions, for loops to iterators), K2 enhances smart casts and type inference, enabling seamless handling of nullable types and complex expressions without manual casting.

Guard Conditions for Safer Control Flow

Set to stabilize in Kotlin 2.2, guard conditions enhance when expressions by allowing conditional checks without variable binding. In a demo, Anton showed processing orders with guard conditions to handle subscriptions and discounts, reducing repetition and ensuring exhaustiveness. Unlike Java’s pattern matching, Kotlin leverages existing destructuring to avoid redundancy, with guard conditions adding logical safety by enforcing checks (e.g., amount > 100) directly in when branches, minimizing errors in complex control flows.

Name-Based Destructuring for Robustness

Anton discussed name-based destructuring, planned for experimental release in Kotlin 2.4. Unlike positional destructuring, which risks logical errors during refactoring, name-based destructuring matches variable names to class properties, improving readability and safety. This feature extends to non-data classes and sealed hierarchies, with plans to deprecate positional destructuring in future versions (e.g., Kotlin 3.0), ensuring long-term language consistency while maintaining backward compatibility.

Context Parameters for Scoped APIs

Context parameters, entering beta in Kotlin 2.2, enable scoped extension functions for type-safe builders, often mistaken for DSLs. Anton demonstrated a client-building DSL where an infix extension function for dates (e.g., 10 March 2000) was restricted to a specific context, preventing global namespace pollution. This feature supports library developers in creating intuitive APIs, such as dependency injection-like logger scoping, reducing boilerplate and enhancing code clarity without compromising safety.

Rich Errors for Expressive Error Handling

Planned for experimental release in Kotlin 2.4, rich errors (previously called union types for errors) introduce a new error class syntax to distinguish error types explicitly. In a demo, Anton showed how rich errors improve over null-based error handling in functions like fetchUser and parseUser, enabling clear differentiation between network and parsing errors. Using when expressions, developers gain exhaustiveness checks and readable error handling, avoiding the verbosity of sealed hierarchies or result types.

Enhancing Compiler Safety with Return Value Checks

Anton highlighted a Kotlin 2.2 feature that mandates checking return values for standard library functions, preventing logical errors like missing return statements or incorrect function calls (e.g., using sort instead of sorted). By marking core functions with annotations, the compiler issues warnings for unused return values, reducing bugs like those in a demo where sorting a mutable list failed due to an overlooked return. This opt-in feature will expand to application code, enhancing reliability.

Links:

PostHeaderIcon [AWSReInforce2025] AWS Heroes launch insights (COM220)

Lecturer

The panel comprises AWS Heroes who contribute extensively to the global cloud community through technical content, open-source projects, and educational initiatives. Their collective expertise spans serverless architecture, security automation, and generative AI integration across AWS services.

Abstract

The discussion analyzes keynote announcements through the lens of practicing architects, emphasizing simplification of security onboarding, unified interfaces for AI model management, and enhanced visibility into complex systems. The Heroes establish that while new capabilities emerge, the overarching theme centers on reducing operational friction without sacrificing control.

Simplification as Strategic Imperative

Security complexity impedes adoption. The keynote reveals multiple features designed to streamline configuration:

  • WAF Console Redesign: Natural language rule creation reduces setup time from hours to minutes
  • Shield Network Security Director: Centralized policy orchestration across accounts and regions
  • IAM Access Analyzer Internal Findings: Automated detection of unused roles and cross-account assumptions

These enhancements transform security from a configuration burden into an enablement layer. The Heroes note that practitioners often avoid modifying working CloudFront distributions due to fear of regression; simplified interfaces mitigate this paralysis.

Unified Model Control Plane (MCP)

The Model Control Plane introduces a standardized interface for AI model interaction:

MCP Endpoint → Authentication → Rate Limiting → Model Routing

Analogous to USB-C, MCP eliminates custom integration per provider. However, the panel cautions that universal interfaces require rigorous trust validation—public charging stations demonstrate how convenience enables supply chain attacks. Organizations must implement:

  • Provider allowlisting
  • Request signing verification
  • Response integrity checks

Visibility and Operational Confidence

New dashboards and AI-powered summaries in Security Hub provide contextual intelligence:

{
  "finding": "CryptoMining EC2",
  "ai_summary": "Instance i-1234567890 shows 5000+ connections to known mining pools",
  "recommended_action": "Isolate and scan"
}

The Heroes emphasize that visibility without action creates alert fatigue. Integration with EventBridge enables automated containment—revoking sessions, quarantining instances—closing the loop from detection to resolution.

Generative AI Risk Management

Security must not lag innovation. The panel discusses patterns for safe adoption:

  1. Prompt Injection Prevention: Input validation, output filtering via Bedrock Guardrails
  2. Model Version Pinning: Immutable references in CodePipeline
  3. Audit Trail Preservation: Structured logging of prompt/response pairs

They stress that hype cycles drive premature adoption; organizations should maintain baseline controls before experimenting with emerging capabilities.

Community Perspective on Innovation Velocity

The Heroes observe that AWS prioritizes practitioner feedback. Features like exportable ACM certificates and active threat defense in Network Firewall address real operational pain points. This collaborative evolution ensures security keeps pace with development velocity.

Conclusion: Security as Innovation Substrate

The keynote demonstrates that mature cloud platforms succeed by reducing cognitive load while preserving granularity. Simplified interfaces, unified control planes, and contextual visibility create an environment where security enables rather than impedes progress. The Heroes conclude that organizations which treat security as infrastructure will achieve both velocity and resilience.

Links:

PostHeaderIcon [KotlinConf2025] Build your Kotlin and Android apps with Buck2

Sergei Rybalkin, a software engineer from Meta, introduced the audience to Buck2, an open-source build system that is now equipped to support Kotlin and Android applications. In a concise and informative presentation, Rybalkin detailed how Buck2, a successor to the original Buck system, addresses the need for a fast and scalable build solution, particularly for large-scale projects like those at Meta. The talk centered on Buck2’s core principles and its capabilities for accelerating development cycles and ensuring consistent, reliable builds.

The Power of a Scalable Build System

Rybalkin began by outlining the motivation behind Buck2. He explained that as projects grow in size and complexity, traditional build systems often struggle to keep up, leading to slow incremental iterations and hindered developer productivity. Buck2 was designed to overcome these challenges by focusing on key areas such as parallelism and a highly opinionated approach to optimization. The talk revealed that Buck2’s architecture allows it to execute build tasks with remarkable efficiency, a crucial factor for Meta’s own internal development processes. Rybalkin also touched on advanced capabilities like Remote Execution and the Build Tools API, which further enhance the system’s performance and flexibility.

A Blueprint for Optimization

The presentation also shed light on Buck2’s philosophy of “opinionated optimization.” Rybalkin clarified that this means the system takes a firm stance on how things should be done to achieve the best results. For example, if a particular feature or integration does not perform well, the Buck2 team may choose to drop support for it entirely, rather than provide a subpar experience. This selective approach ensures that the build system remains fast and reliable, even as it handles a multitude of dependencies and complex configurations. Rybalkin underscored the fact that the open-source version of Buck2 is almost identical to the internal solution used at Meta, offering the community the same powerful tools and optimizations that drive one of the world’s largest development teams. He concluded by encouraging the audience to try Buck2 and provide feedback, underscoring the collaborative nature of open-source development.

Links:

PostHeaderIcon [NDCOslo2024] Hub-Spoke Virtual Networks in Azure – Bastiaan Wassenaar

In the labyrinthine landscape of Azure’s azure architecture, where connectivity contends with compliance, Bastiaan Wassenaar, a cloud custodian and connectivity connoisseur, clarifies the conundrum of hub-spoke virtual networks. As a Dutch devops dynamo, Bastiaan blueprints the bedrock—endpoints, peering, policies—propelling practitioners past perplexities in private provisioning. His session, a symphony of safeguards and setups, spotlights the saga from service sentinels to spoke sanctuaries, ensuring egress elegance and ingress integrity.

Bastiaan banters on boredom’s behalf: vnet vexations vex veterans, yet victory vaults with vigilance. He heralds history: vnet’s 2014 genesis, endpoints’ evolution, private peers’ precision—pivoting from public perils to partitioned paradises.

Foundations of Fortification: Endpoints and Evolutions

Service endpoints erect ramparts: subnet sentries shielding storage, SQL sans sprawl. Bastiaan bewails bandwidth burdens—10Gbps ceilings—yet blesses them as basics, bridging to private endpoints’ purity: dedicated daisy-chains, DNS delegations demystified.

Hub-spoke’s heartbeat: central hub harboring firewalls, spokes siphoning spokes—peering propagates prefixes, UDRs usher unicast. Bastiaan blueprints: Azure Firewall’s fabric, forced tunneling fortifying flows.

Orchestrating the Orbit: Peering, Policies, and Proxies

Peering’s pact: global gateways, transitive taboos—spokes supplicate hubs for harmony. Bastiaan bemoans BGP’s burdens—bidirectional broadcasts—yet bows to basics: static routes suffice for simplicity.

Policies propel protection: NSGs nestle at NICs, FW’s finesse filters flows. Bastiaan broadcasts best bets: hub’s hegemony, spokes’ seclusion—egress egressing exclusively, ingress inspecting intently.

DNS’s Dominion: Delegations and Dilemmas

DNS dances delicately: private endpoints’ FQDNs, hub’s handlers hijacking queries. Bastiaan bemoans blunders—external IPs eclipsing internals—yet extols overrides: custom configurations, conditional forwarding.

His hack: hosts’ hacks for haste, yet hub’s hegemony harmonizes hordes. Bastiaan broadcasts: reboot realms for resolution—vnet’s vicissitudes vanquished.

Victory’s Vista: Vigilance in Vastness

Bastiaan’s benediction: hub-spoke as haven, harmonizing hazards—history heeded, hurdles hurdled. His hurrah: harness helpers, heed heuristics—Azure’s arsenal awaits.

Links:

PostHeaderIcon Restoring Bluetooth on Asus N751 After Migrating to Windows 11

Note: The Asus N751JK remains a powerhouse machine. However, Microsoft has arbitrarily denied official Windows 11 migration to this series and other 4th-gen Intel systems. While users can bypass these artificial restrictions, hardware compatibility issues, specifically regarding Bluetooth, are common. This guide addresses how to fix those “unsupported” errors.

One of the most frustrating hurdles after forced migration is the total loss of Bluetooth functionality. In the Device Manager, this typically appears as a generic entry with a yellow exclamation mark and the error: “Windows has stopped this device because it has reported problems (Code 43).”


The Root Cause: Modern Power Management vs. Legacy Hardware

The core of the issue lies in how Windows 11 manages internal USB components. The Bluetooth module in the N751JK is technically a USB-connected device. Windows 11 uses an aggressive “Energy Efficient” protocol known as USB Selective Suspend.

Because the N751’s hardware was designed in 2014, it does not fully support the modern “handshake” required to wake up from these deep sleep states. When Windows tries to save power, the Bluetooth chip “falls asleep” and fails to wake up, leading to the Code 43 crash. To fix this, we must use a stable legacy driver and disable these power-saving constraints.


Step 1: Install the Stable Legacy Driver

First, we must move away from the generic drivers provided by Windows Update. The following Intel driver, though designated for Windows 10, provides the necessary stability for the Windows 11 environment.

Detail Specification
Device Name Intel(R) Wireless Bluetooth(R) 4.0 + HS Adapter
Driver Version 17.1.1529.1620
Driver Date 2015-07-13
Vendor Intel

Download Source: Official Driver Repository via Driverscape


Step 2: Disable USB Selective Suspend

Installing the driver is only half the battle. To prevent the Code 43 error from returning, you must disable the global setting that allows Windows to “unplug” your Bluetooth module internally.

  1. Search for “Edit Power Plan” in the Windows Start menu and open it.
  2. Click on “Change advanced power settings.”
  3. Locate and expand “USB settings” > “USB selective suspend setting.”
  4. Change both “On battery” and “Plugged in” to Disabled.
  5. Click Apply, then OK, and restart your laptop.

Conclusion

By bypassing the aggressive “Energy Efficient” states that Windows 11 tries to impose on older hardware, we can restore full functionality to the Asus N751JK. This fix proves that with the right configuration, these “unsupported” machines are still highly capable in a modern OS environment.

PostHeaderIcon Option[Scala] != Optional

Java Optional and Scala Option: A Shared Goal, Divergent Philosophies

The absence of a value is one of the most deceptively complex problems in software engineering. For decades, mainstream programming languages relied on a single mechanism to represent it: null. While convenient, this design choice has proven to be one of the most costly abstractions in computing, as famously described by Tony Hoare as his “billion-dollar mistake”. Both Java and Scala eventually introduced explicit abstractions—Optional in Java and Option in Scala—to address this long-standing issue. Although these constructs appear similar on the surface, their design, intended usage, and expressive power differ in ways that reflect the deeper philosophies of their respective languages.

Understanding these differences requires examining not only their APIs, but also how they are used in real code.

Historical Background and Design Motivation

Scala introduced Option as a core concept from its earliest releases. Rooted in functional programming traditions, Scala treats the presence or absence of a value as a fundamental modeling concern. The language encourages developers to encode uncertainty directly into types and to resolve it through composition rather than defensive checks.

Java’s Optional, introduced much later in Java 8, emerged in a very different context. It was part of a cautious modernization effort that added functional elements without breaking compatibility with an enormous existing ecosystem. As a result, Optional was intentionally constrained and positioned primarily as a safer alternative to returning null from methods.

Modeling Presence and Absence

In Scala, an optional value is represented as either Some(value) or None. This is a closed hierarchy, and the distinction is explicit at all times.

def findUser(id: Int): Option[String] =
  if (id == 1) Some("Alice") else None

In Java, the equivalent method returns an Optional created through a factory method.

Optional<String> findUser(int id) {
    return id == 1 ? Optional.of("Alice") : Optional.empty();
}

At first glance, these examples appear nearly identical. The difference becomes more pronounced in how these values are consumed and composed.

Consumption and Transformation

Scala’s Option integrates deeply with the language’s expression-oriented style. Transformations are natural and idiomatic, and optional values behave much like collections with zero or one element.

val upperName =
  findUser(1)
    .map(_.toUpperCase)
    .filter(_.startsWith("A"))

In this example, absence propagates automatically. If findUser returns None, the entire expression evaluates to None without any additional checks.

Java’s Optional supports similar operations, but the style is more constrained and often more verbose.

Optional<String> upperName =
    findUser(1)
        .map(String::toUpperCase)
        .filter(name -> name.startsWith("A"));

Although the semantics are similar, Java’s syntax and type system make these chains feel more deliberate and less fluid, reinforcing the idea that Optional is a special-purpose construct rather than a universal modeling tool.

Extracting Values: Intentional Friction vs Idiomatic Resolution

Scala encourages developers to resolve optional values through pattern matching or total functions such as getOrElse.

val name = findUser(2) match {
  case Some(value) => value
  case None        => "Unknown"
}

A concise fallback can also be expressed directly:

val name = findUser(2).getOrElse("Unknown")

In Java, extracting a value is intentionally more guarded. While get() exists, its use is discouraged in favor of safer alternatives.

String name = findUser(2).orElse("Unknown");

The difference is cultural rather than technical. In Scala, resolving an Option is a normal part of control flow. In Java, consuming an Optional is treated as an exceptional act that should be handled carefully and explicitly.

Optional Values in Composition

Scala excels at composing multiple optional computations using flatMap or for-comprehensions.

for {
  user  <- findUser(1)
  email <- findEmail(user)
} yield email

This code expresses dependent computations declaratively. If any step yields None, the entire expression evaluates to None.

In Java, the same logic requires more explicit wiring.

Optional<String> email =
    findUser(1).flatMap(user -> findEmail(user));

While functional, the Java version becomes less readable as the number of dependent steps increases.

Usage as Fields and Parameters

Scala allows Option to be used freely as a field or parameter type, which is common and idiomatic.

case class User(name: String, email: Option[String])

Java, by contrast, discourages the use of Optional in fields or parameters, even though it is technically possible.

// Generally discouraged
class User {
    Optional<String> email;
}

This contrast highlights Scala’s confidence in Option as a foundational abstraction, while Java treats Optional as a boundary marker in API design.

Philosophical Implications

The contrast between Option and Optional mirrors the broader philosophies of Scala and Java. Scala embraces expressive power and abstraction to manage complexity. Java favors incremental evolution and clarity, even when that limits expressiveness.

Both approaches are valid, and both significantly reduce errors when used appropriately.

Conclusion

Java’s Optional and Scala’s Option address the same fundamental problem, yet they do so in ways that reflect the deeper identity of their ecosystems. Scala’s Option is a first-class participant in program structure, encouraging composition and declarative reasoning. Java’s Optional is a carefully scoped enhancement, designed to improve API safety without redefining the language.

What appears to be a minor syntactic distinction is, in reality, a clear illustration of two distinct approaches to software design on the JVM.

PostHeaderIcon [KotlinConf2024] Compose Multiplatform Evolves on iOS and Beyond

At KotlinConf2024, Sebastian Aigner, a JetBrains developer advocate, unveiled advancements in Compose Multiplatform, now in beta for iOS and alpha for web. Extending beyond business logic, Compose enables shared UI across platforms, integrating native capabilities. Sebastian showcased new common APIs—previews, resources, lifecycle, navigation, and UI testing—alongside iOS-specific enhancements like accessibility and scroll physics. Through live demos, he demonstrated how these features simplify cross-platform development, inviting developers to shape Compose’s future with feedback.

A Year of Progress for Compose Multiplatform

Since its debut at KotlinConf2023, Compose Multiplatform has matured significantly. Sebastian highlighted its role in sharing UI code, complementing Kotlin Multiplatform’s business logic sharing. On Android, it leverages Jetpack Compose; on desktop, it powers JetBrains Toolbox; and on iOS, it reached beta status at KotlinConf2024. The web target hit alpha, broadening its reach. Progress spans accessibility, navigation, text input, and scroll physics, with most features now stable or experimental, ready for developers to adopt and refine through real-world use.

iOS-Specific Enhancements

Compose Multiplatform on iOS now feels native, thanks to revamped scroll physics mirroring iOS’s overscroll and spring effects. Sebastian demonstrated accessibility improvements, with components supporting VoiceOver and gesture navigation out of the box, provided content descriptions are added. Interop with SwiftUI allows popups to span the screen, and window insets APIs handle notches and dynamic islands, ensuring full-screen rendering. These enhancements make iOS apps built with Compose visually and functionally indistinguishable from native counterparts, enhancing user experience.

Common Resources for Seamless UI

The new common resources API simplifies asset management. Sebastian showed how to add drawables and strings in a composeResources directory, accessed via a type-safe res object. In a demo, he added a banner image and a localized conference description, with Fleet auto-generating accessors. Support for multimodule resources and translations (e.g., German dark mode) ensures flexibility. This API, familiar from Android, reduces boilerplate, letting developers focus on crafting polished, platform-agnostic UIs with minimal effort.

Lifecycle and View Models in Common Code

Compose Multiplatform now supports common lifecycle and view model APIs, enabling robust app architecture. Sebastian demonstrated a lifecycle logger tracking states like onCreate and onPause, with collectAsStateWithLifecycle ensuring efficient flow collection. In a view model demo, he outsourced mood-tracking logic, using a factory function to instantiate it. Integration with Koin for dependency injection and lifecycle-aware state collection streamlines development, making MVVM patterns viable across platforms without platform-specific workarounds.

Navigation for Cross-Platform Apps

Navigation, a cornerstone of multiplatform apps, is now available via a Jetpack Navigation-inspired API. Sebastian built a demo app with a fruit list and detail pages, using a NavHost and NavController for stack-based navigation. Features like window insets padding, animated transitions, and rememberSaveable for state persistence ensure a native feel. Type-safe routing with Kotlinx.serialization is in development, reducing errors. This API, while optional, simplifies porting Android navigation logic to iOS and beyond, enhancing developer productivity.

UI Testing and Community Feedback

A new common UI testing API allows writing tests once for all platforms. Sebastian showed a test verifying a composable’s text content, executed across targets. This reduces testing overhead, ensuring consistent behavior. He urged developers to try these features, citing the Compose Multiplatform portal (jb.compose) for documentation. Feedback via the Kotlin Slack and issue tracker is vital, as community input drives stabilization. With support for features like strong skipping mode and shared element transitions, Compose continues to evolve dynamically.

Links:

PostHeaderIcon [KotlinConf2024] Compose Multiplatform Evolves on iOS and Beyond

At KotlinConf2024, Sebastian Aigner, a JetBrains developer advocate, unveiled advancements in Compose Multiplatform, now in beta for iOS and alpha for web. Extending beyond business logic, Compose enables shared UI across platforms, integrating native capabilities. Sebastian showcased new common APIs—previews, resources, lifecycle, navigation, and UI testing—alongside iOS-specific enhancements like accessibility and scroll physics. Through live demos, he demonstrated how these features simplify cross-platform development, inviting developers to shape Compose’s future with feedback.

A Year of Progress for Compose Multiplatform

Since its debut at KotlinConf2023, Compose Multiplatform has matured significantly. Sebastian highlighted its role in sharing UI code, complementing Kotlin Multiplatform’s business logic sharing. On Android, it leverages Jetpack Compose; on desktop, it powers JetBrains Toolbox; and on iOS, it reached beta status at KotlinConf2024. The web target hit alpha, broadening its reach. Progress spans accessibility, navigation, text input, and scroll physics, with most features now stable or experimental, ready for developers to adopt and refine through real-world use.

iOS-Specific Enhancements

Compose Multiplatform on iOS now feels native, thanks to revamped scroll physics mirroring iOS’s overscroll and spring effects. Sebastian demonstrated accessibility improvements, with components supporting VoiceOver and gesture navigation out of the box, provided content descriptions are added. Interop with SwiftUI allows popups to span the screen, and window insets APIs handle notches and dynamic islands, ensuring full-screen rendering. These enhancements make iOS apps built with Compose visually and functionally indistinguishable from native counterparts, enhancing user experience.

Common Resources for Seamless UI

The new common resources API simplifies asset management. Sebastian showed how to add drawables and strings in a composeResources directory, accessed via a type-safe res object. In a demo, he added a banner image and a localized conference description, with Fleet auto-generating accessors. Support for multimodule resources and translations (e.g., German dark mode) ensures flexibility. This API, familiar from Android, reduces boilerplate, letting developers focus on crafting polished, platform-agnostic UIs with minimal effort.

Lifecycle and View Models in Common Code

Compose Multiplatform now supports common lifecycle and view model APIs, enabling robust app architecture. Sebastian demonstrated a lifecycle logger tracking states like onCreate and onPause, with collectAsStateWithLifecycle ensuring efficient flow collection. In a view model demo, he outsourced mood-tracking logic, using a factory function to instantiate it. Integration with Koin for dependency injection and lifecycle-aware state collection streamlines development, making MVVM patterns viable across platforms without platform-specific workarounds.

Navigation for Cross-Platform Apps

Navigation, a cornerstone of multiplatform apps, is now available via a Jetpack Navigation-inspired API. Sebastian built a demo app with a fruit list and detail pages, using a NavHost and NavController for stack-based navigation. Features like window insets padding, animated transitions, and rememberSaveable for state persistence ensure a native feel. Type-safe routing with Kotlinx.serialization is in development, reducing errors. This API, while optional, simplifies porting Android navigation logic to iOS and beyond, enhancing developer productivity.

UI Testing and Community Feedback

A new common UI testing API allows writing tests once for all platforms. Sebastian showed a test verifying a composable’s text content, executed across targets. This reduces testing overhead, ensuring consistent behavior. He urged developers to try these features, citing the Compose Multiplatform portal (jb.compose) for documentation. Feedback via the Kotlin Slack and issue tracker is vital, as community input drives stabilization. With support for features like strong skipping mode and shared element transitions, Compose continues to evolve dynamically.

Links:

PostHeaderIcon [DevoxxGR2025] Optimized Kubernetes Scaling with Karpenter

Alex König, an AWS expert, delivered a 39-minute talk at Devoxx Greece 2025, exploring how Karpenter enhances Kubernetes cluster autoscaling for speed, cost-efficiency, and availability.

Karpenter’s Dynamic Autoscaling

König introduced Karpenter as an open-source, Kubernetes-native autoscaling solution, contrasting it with the traditional Cluster Autoscaler. Unlike the latter, which relies on uniform node groups (e.g., nodes with four CPUs and 16GB RAM), Karpenter uses the EC2 Fleet API to dynamically provision nodes tailored to workload needs. For instance, if a pod requires one CPU, Karpenter allocates a node with minimal excess capacity, avoiding resource waste. This right-sizing, combined with groupless scaling, enables faster and more cost-effective scaling, especially in dynamic environments.

Ensuring Availability with Constraints

König addressed availability challenges reported by users, emphasizing Kubernetes-native scheduling constraints to mitigate disruptions. Topology spread constraints distribute pods across availability zones, reducing the risk of downtime if a node fails. Pod disruption budgets, affinity/anti-affinity rules, and priority classes further ensure critical workloads are scheduled appropriately. For stateful workloads using EBS, König recommended setting the volume binding mode to “wait for first consumer” to avoid pod-volume mismatches across zones, preventing crashes and ensuring reliability.

Integrating with KEDA for Application Scaling

For advanced scaling, König highlighted combining Karpenter with KEDA for event-driven, application-specific scaling. KEDA scales pods based on metrics like Kafka topic sizes or SQS queues, beyond CPU/memory. Karpenter then provisions nodes for pending pods, enabling seamless scaling for workloads like flash sales. König outlined a four-step migration from Cluster Autoscaler to Karpenter, emphasizing its simplicity and open-source documentation.

Links