<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Said Olano</title>
    <description>The latest articles on DEV Community by Said Olano (@said_olano).</description>
    <link>https://dev.to/said_olano</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1173572%2F559076dd-fc31-431a-bd48-19ed5af74573.jpeg</url>
      <title>DEV Community: Said Olano</title>
      <link>https://dev.to/said_olano</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/said_olano"/>
    <language>en</language>
    <item>
      <title>AWS DynamoDB: Mastering NoSQL Database Patterns (2026-08-27 02:21)</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Thu, 27 Aug 2026 02:21:05 +0000</pubDate>
      <link>https://dev.to/said_olano/aws-dynamodb-mastering-nosql-database-patterns-2026-08-27-0221-2pg1</link>
      <guid>https://dev.to/said_olano/aws-dynamodb-mastering-nosql-database-patterns-2026-08-27-0221-2pg1</guid>
      <description>&lt;h1&gt;
  
  
  AWS DynamoDB: Mastering NoSQL Database Patterns
&lt;/h1&gt;

&lt;p&gt;Amazon DynamoDB is a fully managed, serverless NoSQL database that delivers single-digit millisecond performance at any scale. However, unlocking its full potential requires a shift in mindset from traditional relational modeling. This post explores the core patterns that make DynamoDB applications fast, scalable, and cost-effective.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Fundamentals
&lt;/h2&gt;

&lt;p&gt;Before diving into patterns, it's essential to understand DynamoDB's building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Partition Key (PK)&lt;/strong&gt;: Determines the physical partition where data is stored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sort Key (SK)&lt;/strong&gt;: Enables sorting and range queries within a partition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Items&lt;/strong&gt;: Individual records, up to 400 KB in size.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attributes&lt;/strong&gt;: Fields within an item (schemaless beyond the keys).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike SQL databases, DynamoDB rewards &lt;strong&gt;denormalization&lt;/strong&gt; and modeling around your &lt;strong&gt;access patterns&lt;/strong&gt; rather than your data's logical structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 1: Single-Table Design
&lt;/h2&gt;

&lt;p&gt;The most powerful (and controversial) DynamoDB pattern is storing multiple entity types in a single table. This reduces round trips and leverages DynamoDB's partitioning efficiently.&lt;/p&gt;

&lt;p&gt;Consider an e-commerce app with &lt;code&gt;Users&lt;/code&gt;, &lt;code&gt;Orders&lt;/code&gt;, and &lt;code&gt;Products&lt;/code&gt;. Instead of three tables, use one with generic key names:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PK&lt;/th&gt;
&lt;th&gt;SK&lt;/th&gt;
&lt;th&gt;Attributes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;USER#123&lt;/td&gt;
&lt;td&gt;PROFILE&lt;/td&gt;
&lt;td&gt;name, email&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;USER#123&lt;/td&gt;
&lt;td&gt;ORDER#1001&lt;/td&gt;
&lt;td&gt;total, status, date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ORDER#1001&lt;/td&gt;
&lt;td&gt;PRODUCT#A9&lt;/td&gt;
&lt;td&gt;qty, price&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;By overloading the partition and sort keys, you can fetch a user and all their orders in a single query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;KeyConditionExpression&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PK&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;USER#123&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pattern 2: Composite Sort Keys
&lt;/h2&gt;

&lt;p&gt;Encode hierarchical relationships into sort keys to enable flexible range queries. For example, model a location hierarchy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SK: COUNTRY#USA#STATE#CA#CITY#SF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then query with &lt;code&gt;begins_with&lt;/code&gt; to retrieve all items under a given scope:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;KeyConditionExpression&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PK&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;LOCATIONS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
        &lt;span class="nc"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SK&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;begins_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;COUNTRY#USA#STATE#CA&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pattern 3: Global Secondary Indexes (GSIs)
&lt;/h2&gt;

&lt;p&gt;GSIs let you query data using an alternate key structure. A common technique is &lt;strong&gt;index overloading&lt;/strong&gt;, where a single GSI serves multiple access patterns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Create a GSI to query orders by status
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;IndexName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GSI1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;KeyConditionExpression&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GSI1PK&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;STATUS#SHIPPED&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Best practices for GSIs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project only the attributes you need to reduce cost.&lt;/li&gt;
&lt;li&gt;Remember GSIs are eventually consistent.&lt;/li&gt;
&lt;li&gt;Watch for hot partitions on low-cardinality keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pattern 4: Write Sharding for Hot Partitions
&lt;/h2&gt;

&lt;p&gt;When a single partition key receives disproportionate traffic (e.g., a trending item), you can distribute writes across synthetic shards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;

&lt;span class="n"&gt;shard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PRODUCT#TRENDING#&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;shard&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To read all data, query each shard in parallel and merge the results. This spreads throughput across multiple partitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 5: Time Series Data
&lt;/h2&gt;

&lt;p&gt;For time-based data, use a partition key that includes a time bucket to avoid unbounded partitions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PK: SENSOR#42#2024-01
SK: 2024-01-15T10:30:00Z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rolling the bucket monthly (or daily for high volume) keeps partitions manageable and supports efficient time-range queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 6: Adjacency List for Many-to-Many
&lt;/h2&gt;

&lt;p&gt;Model graph-like relationships using the adjacency list pattern. Both entities and their relationships live in the same table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PK: USER#1    SK: GROUP#10   (user 1 belongs to group 10)
PK: GROUP#10  SK: USER#1     (reverse lookup via GSI)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A GSI that swaps PK and SK enables bidirectional queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost and Performance Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use on-demand capacity&lt;/strong&gt; for unpredictable workloads; provisioned with auto-scaling for steady traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable DynamoDB Accelerator (DAX)&lt;/strong&gt; for read-heavy, microsecond-latency needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch operations&lt;/strong&gt; (&lt;code&gt;BatchGetItem&lt;/code&gt;, &lt;code&gt;BatchWriteItem&lt;/code&gt;) to reduce network overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leverage TTL&lt;/strong&gt; to automatically expire stale items and reduce storage costs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;DynamoDB shines when you design backward from your application's access patterns. Embrace single-table design, exploit composite keys and GSIs, and plan for scale with write sharding and time bucketing. Master these patterns, and you'll build systems that scale effortlessly from prototype to planet-scale.&lt;/p&gt;

&lt;p&gt;Start by listing every query your application needs—then model your table to satisfy them with the fewest requests possible.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>dynamodb</category>
      <category>nosql</category>
      <category>databasedesign</category>
    </item>
    <item>
      <title>Artifactory: Repository Management for Modern DevOps (2026-08-26 19:53)</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Wed, 26 Aug 2026 19:53:28 +0000</pubDate>
      <link>https://dev.to/said_olano/artifactory-repository-management-for-modern-devops-2026-08-26-1953-139f</link>
      <guid>https://dev.to/said_olano/artifactory-repository-management-for-modern-devops-2026-08-26-1953-139f</guid>
      <description>&lt;h1&gt;
  
  
  Artifactory: Repository Management
&lt;/h1&gt;

&lt;p&gt;In modern software delivery, managing binary artifacts is just as critical as managing source code. JFrog Artifactory has emerged as a leading universal repository manager, providing a single source of truth for all your binaries—from Docker images and npm packages to Maven JARs and Helm charts.&lt;/p&gt;

&lt;p&gt;This post explores the fundamentals of repository management in Artifactory and shares practical guidance for structuring your repositories effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a Repository Manager?
&lt;/h2&gt;

&lt;p&gt;Before diving into specifics, it's worth understanding what problems Artifactory solves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Centralized storage&lt;/strong&gt; for build artifacts across teams and technologies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching of remote dependencies&lt;/strong&gt; to reduce external network calls and improve build reliability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access control&lt;/strong&gt; and security scanning for binaries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promotion workflows&lt;/strong&gt; that move artifacts through environments (dev → staging → production)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Three Repository Types
&lt;/h2&gt;

&lt;p&gt;Artifactory organizes storage into three fundamental repository types. Understanding these is key to a healthy setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Local Repositories
&lt;/h3&gt;

&lt;p&gt;Local repositories host artifacts that your organization produces. These are your internal builds, releases, and snapshots.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;libs-release-local
libs-snapshot-local
docker-local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A common best practice is to separate release and snapshot artifacts to enforce different retention and promotion policies.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Remote Repositories
&lt;/h3&gt;

&lt;p&gt;Remote repositories act as caching proxies for external sources like Maven Central, npmjs, or Docker Hub. When a dependency is requested, Artifactory downloads and caches it locally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maven-central-remote  -&amp;gt;  https://repo1.maven.org/maven2
npm-remote            -&amp;gt;  https://registry.npmjs.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reduces reliance on external services and protects you from upstream outages.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Virtual Repositories
&lt;/h3&gt;

&lt;p&gt;Virtual repositories aggregate multiple local and remote repositories under a single URL. Consumers point to one endpoint, and Artifactory resolves artifacts across the underlying repos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maven-virtual
├── libs-release-local
├── libs-snapshot-local
└── maven-central-remote
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This abstraction is powerful: you can reorganize backend repositories without changing client configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Recommended Naming Convention
&lt;/h2&gt;

&lt;p&gt;Consistent naming prevents chaos as your instance grows. A widely adopted pattern is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;team&amp;gt;-&amp;lt;technology&amp;gt;-&amp;lt;maturity&amp;gt;-&amp;lt;type&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;payments-docker-release-local
payments-maven-snapshot-local
frontend-npm-virtual
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Include the repository type suffix (&lt;code&gt;-local&lt;/code&gt;, &lt;code&gt;-remote&lt;/code&gt;, &lt;code&gt;-virtual&lt;/code&gt;) so it's immediately clear how a repository behaves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Repositories via REST API
&lt;/h2&gt;

&lt;p&gt;Automation is essential at scale. Artifactory exposes a comprehensive REST API for creating and configuring repositories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-u&lt;/span&gt; admin:password &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://artifactory.example.com/artifactory/api/repositories/docker-local"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "rclass": "local",
    "packageType": "docker",
    "dockerApiVersion": "V2"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For infrastructure-as-code enthusiasts, the official Terraform provider lets you declare repositories declaratively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"artifactory_local_docker_v2_repository"&lt;/span&gt; &lt;span class="s2"&gt;"docker_local"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;key&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"docker-local"&lt;/span&gt;
  &lt;span class="nx"&gt;tag_retention&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
  &lt;span class="nx"&gt;max_unique_tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cleanup and Retention
&lt;/h2&gt;

&lt;p&gt;Binary storage grows quickly. Without a strategy, disk usage becomes unmanageable. Consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Retention policies&lt;/strong&gt; that limit the number of snapshots or Docker tags kept&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduled cleanup jobs&lt;/strong&gt; using AQL (Artifactory Query Language) to identify stale artifacts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage quotas&lt;/strong&gt; to trigger alerts before you run out of space&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's an AQL example that finds artifacts not downloaded in 90 days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;items.find(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"libs-snapshot-local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stat.downloaded"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"$before"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"90d"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Security Best Practices
&lt;/h2&gt;

&lt;p&gt;Repository management isn't complete without access control:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;permission targets&lt;/strong&gt; to grant least-privilege access per repository&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;JFrog Xray&lt;/strong&gt; to scan artifacts for vulnerabilities and license violations&lt;/li&gt;
&lt;li&gt;Restrict &lt;strong&gt;anonymous access&lt;/strong&gt; on production-facing repositories&lt;/li&gt;
&lt;li&gt;Rotate &lt;strong&gt;access tokens&lt;/strong&gt; regularly and prefer them over passwords in CI pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Effective repository management in Artifactory rests on a few core principles: understand the three repository types, adopt a consistent naming convention, automate provisioning, and enforce cleanup and security policies from day one.&lt;/p&gt;

&lt;p&gt;Get these fundamentals right, and Artifactory becomes a reliable backbone for your entire software supply chain—scaling cleanly as your organization and its binaries grow.&lt;/p&gt;

</description>
      <category>artifactory</category>
      <category>devops</category>
      <category>repositorymanagement</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Arquitectura Tradicional vs AI-Native: La Evolución que Necesitas Entender</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Wed, 26 Aug 2026 18:50:23 +0000</pubDate>
      <link>https://dev.to/said_olano/arquitectura-tradicional-vs-ai-native-la-evolucion-que-necesitas-entender-43he</link>
      <guid>https://dev.to/said_olano/arquitectura-tradicional-vs-ai-native-la-evolucion-que-necesitas-entender-43he</guid>
      <description>&lt;h1&gt;
  
  
  Arquitectura Tradicional vs AI-Native: La Evolución que Necesitas Entender
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;Durante los últimos 20 años, hemos construido sistemas backend siguiendo una arquitectura relativamente consistente: usuario → frontend → backend → base de datos. Este modelo ha funcionado bien y sigue siendo válido. Pero algo fundamental cambió en 2023-2024.&lt;/p&gt;

&lt;p&gt;Hoy, si ignoras cómo integrar capacidades de IA en tu arquitectura de software, estás quedando obsoleto. No es hype—es evolución arquitectónica real.&lt;/p&gt;

&lt;p&gt;En este artículo, exploro las diferencias críticas entre la arquitectura tradicional y la arquitectura AI-Native, cómo Spring AI cambia el juego para desarrolladores Java, y por qué tu próximo proyecto debería pensar en LLMs desde el inicio, no como un anexo.&lt;/p&gt;

&lt;h2&gt;
  
  
  La Arquitectura Tradicional: El Modelo que Conocemos
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usuario → Frontend → Backend → Base de Datos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este diagrama ha gobernado el desarrollo de software empresarial por 15+ años:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Interfaz de usuario (web, móvil, desktop)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Lógica de negocio en Java/Spring, Python, Node, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Base de Datos&lt;/strong&gt;: PostgreSQL, MySQL, Oracle, etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Limitaciones de este modelo:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sin contexto inteligente&lt;/strong&gt;: El backend ejecuta lógica predefinida, sin capacidad de razonar sobre contexto&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clasificación binaria&lt;/strong&gt;: Si → No. Sí → Tabla X o Tabla Y. Sin matices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requiere reglas explícitas&lt;/strong&gt;: Cada escenario debe codificarse manualmente&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No escala con complejidad&lt;/strong&gt;: Añadir nuevos casos requiere nuevo código y testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ¿Cuándo funciona aún?
&lt;/h3&gt;

&lt;p&gt;La arquitectura tradicional es perfecta para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Operaciones CRUD básicas&lt;/li&gt;
&lt;li&gt;Lógica transaccional determinista&lt;/li&gt;
&lt;li&gt;Sistemas de reporting&lt;/li&gt;
&lt;li&gt;APIs REST simples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pero falla cuando necesitas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recomendaciones personalizadas&lt;/li&gt;
&lt;li&gt;Clasificación inteligente de datos&lt;/li&gt;
&lt;li&gt;Procesamiento de lenguaje natural&lt;/li&gt;
&lt;li&gt;Decisiones basadas en contexto complejo&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  La Arquitectura AI-Native: El Nuevo Paradigma
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usuario → Frontend → Backend → Spring AI ↔ LLM → Enterprise APIs
                         ↓
                   Vector Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La arquitectura AI-Native introduce componentes nuevos en la pila:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Spring AI: Tu Abstracción Estratégica&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Spring AI es la capa de abstracción que conecta tu backend Java tradicional con modelos de lenguaje (LLMs). Piénsalo como &lt;code&gt;java.net.HttpURLConnection&lt;/code&gt; fue para HTTP hace 15 años.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ChatClient&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;processComplexQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;userInput&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userInput&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Por qué importa:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agnóstico de modelo&lt;/strong&gt;: Cambia entre OpenAI, Claude, Llama sin refactorizar código&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integración con tu stack&lt;/strong&gt;: Funciona nativamente con Spring Boot, Spring Security, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gestión de tokens&lt;/strong&gt;: Maneja limite de contexto automáticamente&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrieval Augmented Generation (RAG)&lt;/strong&gt;: Conecta a bases de datos vectoriales&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;LLM: Tu Inteligencia Contextual&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Un Large Language Model no es un "chatbot". Es una máquina de razonar que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lee y comprende contexto complejo&lt;/li&gt;
&lt;li&gt;Genera texto, código, análisis&lt;/li&gt;
&lt;li&gt;Toma decisiones basadas en matices&lt;/li&gt;
&lt;li&gt;Se alimenta de ejemplos y patrones en sus 7-70B parámetros
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Analiza este fraude potencial: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;transactionData&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
                &lt;span class="s"&gt;"\nReglas de negocio: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;businessRules&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="s"&gt;"\n¿Es fraude? Justifica con 2-3 razones."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;analysis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;strong&gt;Vector Database: Tu Motor de Memoria&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Una base de datos vectorial (Pinecone, Weaviate, Milvus) almacena documentos como embeddings numéricos. Permite búsqueda semántica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"¿Cuál es nuestra política de cancelaciones?"
        ↓
    Embeddings
        ↓
    Vector DB (busca similitud)
        ↓
    Retorna política relevante → LLM → Respuesta precisa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ventaja crítica&lt;/strong&gt;: No necesita palabra exacta. Entiende significado.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Enterprise APIs: Tu Contexto en Tiempo Real&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;El LLM no funciona en vacío. Necesita datos vivos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estado de cuenta del cliente&lt;/li&gt;
&lt;li&gt;Inventario disponible&lt;/li&gt;
&lt;li&gt;Políticas de compañía&lt;/li&gt;
&lt;li&gt;Datos de mercado en tiempo real
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;loanDecision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cliente "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" solicita préstamo de "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usa datos de creditScoreAPI y complianceDB para decidir"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Diferencias Clave: Punto a Punto
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspecto&lt;/th&gt;
&lt;th&gt;Tradicional&lt;/th&gt;
&lt;th&gt;AI-Native&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Decisiones&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Determinísticas (if/else)&lt;/td&gt;
&lt;td&gt;Contextual + razonada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Escalabilidad de lógica&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lineal (una regla = un if)&lt;/td&gt;
&lt;td&gt;Exponencial (el LLM generaliza)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Errores&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Binarios (funciona o no)&lt;/td&gt;
&lt;td&gt;Graduales (respuesta parcialmente correcta)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Actualización&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Redeploy + testing&lt;/td&gt;
&lt;td&gt;Prompt engineering (minutos)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latencia&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ms&lt;/td&gt;
&lt;td&gt;500-2000ms (LLM call)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Costos&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hardware + ops&lt;/td&gt;
&lt;td&gt;Tokens * precio/1M&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Casos de Uso: Dónde Brilla AI-Native
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Análisis de Riesgos Financieros&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tradicional: 47 reglas hard-coded&lt;br&gt;
AI-Native: LLM analiza contexto transaccional completo + historial + señales de mercado&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Atención al Cliente&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tradicional: Chatbot con 500 reglas pre-escritas&lt;br&gt;
AI-Native: Agente que lee base de conocimiento, entiende contexto, genera respuestas coherentes&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Clasificación de Documentos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tradicional: Regex + NLP simple&lt;br&gt;
AI-Native: LLM entiende semántica real, maneja idiomas, detecta fraudes documentales&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Recomendaciones&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tradicional: Filtrado colaborativo&lt;br&gt;
AI-Native: LLM + vector DB genera recomendaciones explicables ("Te recomendamos X porque...")&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementación: Spring AI en Acción
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setup Básico
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@EnableSpringAI&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AiConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ChatClient&lt;/span&gt; &lt;span class="nf"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ChatModel&lt;/span&gt; &lt;span class="n"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ChatClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Consulta Avanzada con RAG
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DocumentAnalysisService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ChatClient&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;VectorStore&lt;/span&gt; &lt;span class="n"&gt;vectorStore&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;analyzeWithContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1. Busca en vector DB&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;relevantDocs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorStore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;search&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SearchRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;withTopK&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// 2. Construye contexto&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relevantDocs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Document:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getContent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;joining&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\n---\n"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

        &lt;span class="c1"&gt;// 3. Llama LLM con contexto&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pregunta: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Contexto relevante:\n"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Migración: No Es Todo o Nada
&lt;/h2&gt;

&lt;p&gt;No necesitas reescribir tu backend. La arquitectura AI-Native es &lt;strong&gt;aditiva&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fase 1&lt;/strong&gt;: Mantén tu stack actual&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fase 2&lt;/strong&gt;: Agrega Spring AI para casos de uso específicos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fase 3&lt;/strong&gt;: Integra vector DB donde agregue valor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fase 4&lt;/strong&gt;: Expande gradualmente&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ejemplo: Mantén tu backend Java Spring Boot intacto, pero agrega un servicio de análisis de riesgos con LLM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Costos Reales
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Preocupación común&lt;/strong&gt;: "¿No será caro?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Respuesta&lt;/strong&gt;: Depende, pero generalmente no.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI API&lt;/strong&gt;: ~$0.0005-0.002 por 1K tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consulta típica&lt;/strong&gt;: 1000-2000 tokens = $0.001-0.003&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;vs. ing. tradicional&lt;/strong&gt;: Una consulta = 2-4 horas de dev time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ROI&lt;/strong&gt;: Una consulta ML = ~10 líneas de lógica tradicional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitaciones: Sé Honesto
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Dónde AI-Native falla:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transacciones críticas sin explicabilidad (pagos, créditos)&lt;/li&gt;
&lt;li&gt;Sistemas embebidos con latencia crítica (control en tiempo real)&lt;/li&gt;
&lt;li&gt;Datasets ultra-pequeños (&amp;lt;1000 ejemplos)&lt;/li&gt;
&lt;li&gt;Donde el hallucination es inaceptable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solución&lt;/strong&gt;: Híbridos. Usa AI-Native para análisis, backend tradicional para ejecución.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión: La Pregunta Ya No Es "Si", Sino "Cuándo"
&lt;/h2&gt;

&lt;p&gt;En 2024, la arquitectura AI-Native no es un experimento de IA. Es infraestructura empresarial.&lt;/p&gt;

&lt;p&gt;Si diseñas una nueva aplicación hoy sin considerar cómo AI + LLMs pueden mejorar tu propuesta de valor, estás dejando dinero y capacidad en la mesa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Siguientes pasos:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Experimenta con Spring AI en un caso de uso no crítico&lt;/li&gt;
&lt;li&gt;Mide latencia y costos reales en tu stack&lt;/li&gt;
&lt;li&gt;Expande a producción donde agregue valor&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El futuro no es "AI o Backend Tradicional". Es &lt;strong&gt;ambos&lt;/strong&gt;, integrados inteligentemente.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;¿Te gustaría explorar un caso específico en tu dominio?&lt;/strong&gt; Fintech, e-commerce, seguros—cada industria tiene oportunidades únicas donde AI-Native cambia el juego.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>ai</category>
      <category>java</category>
      <category>backend</category>
    </item>
    <item>
      <title>Keycloak: A Deep Dive into Open Source Identity and Access Management (2026-08-26 14:42)</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Wed, 26 Aug 2026 14:42:04 +0000</pubDate>
      <link>https://dev.to/said_olano/keycloak-a-deep-dive-into-open-source-identity-and-access-management-2026-08-26-1442-4g8o</link>
      <guid>https://dev.to/said_olano/keycloak-a-deep-dive-into-open-source-identity-and-access-management-2026-08-26-1442-4g8o</guid>
      <description>&lt;h1&gt;
  
  
  Keycloak: Open Source IAM Solution
&lt;/h1&gt;

&lt;p&gt;Managing authentication and authorization across modern applications is a complex challenge. Building these capabilities from scratch is error-prone and time-consuming. &lt;strong&gt;Keycloak&lt;/strong&gt;, an open source Identity and Access Management (IAM) solution maintained by Red Hat, solves this problem by providing a robust, standards-based platform out of the box.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Keycloak?
&lt;/h2&gt;

&lt;p&gt;Keycloak is a self-hosted IAM server that centralizes authentication and authorization for your applications and services. Instead of each application implementing its own login logic, they delegate that responsibility to Keycloak.&lt;/p&gt;

&lt;p&gt;Key features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single Sign-On (SSO)&lt;/strong&gt; and Single Sign-Out across applications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity Brokering&lt;/strong&gt; with social login (Google, GitHub, Facebook, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Federation&lt;/strong&gt; with LDAP and Active Directory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard protocol support&lt;/strong&gt;: OpenID Connect, OAuth 2.0, and SAML 2.0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fine-grained authorization&lt;/strong&gt; with role-based and attribute-based access control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin Console&lt;/strong&gt; and &lt;strong&gt;Account Console&lt;/strong&gt; for management&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Core Concepts
&lt;/h2&gt;

&lt;p&gt;Understanding a few key concepts is essential before working with Keycloak.&lt;/p&gt;

&lt;h3&gt;
  
  
  Realms
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;realm&lt;/strong&gt; is an isolated space that manages a set of users, credentials, roles, and clients. Realms are completely separated from one another. The &lt;code&gt;master&lt;/code&gt; realm is used to administer Keycloak itself, while you create dedicated realms for your applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clients
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;client&lt;/strong&gt; is an application or service that wants to use Keycloak for authentication. Clients can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Confidential&lt;/strong&gt;: Backend services that can securely store a secret.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public&lt;/strong&gt;: Frontend apps (SPAs, mobile) that cannot keep secrets confidential.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Roles and Groups
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Roles&lt;/strong&gt; define permissions, and can be realm-level or client-level. &lt;strong&gt;Groups&lt;/strong&gt; allow you to organize users and assign roles collectively, simplifying permission management at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with Docker
&lt;/h2&gt;

&lt;p&gt;The fastest way to try Keycloak is via Docker. The following command starts a development instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KEYCLOAK_ADMIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KEYCLOAK_ADMIN_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin &lt;span class="se"&gt;\&lt;/span&gt;
  quay.io/keycloak/keycloak:latest &lt;span class="se"&gt;\&lt;/span&gt;
  start-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once running, access the admin console at &lt;code&gt;http://localhost:8080&lt;/code&gt; and log in with the credentials above.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;start-dev&lt;/code&gt; mode uses an in-memory database and disables HTTPS. Never use it in production.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Integrating an Application
&lt;/h2&gt;

&lt;p&gt;Here's a typical OpenID Connect flow for a web application:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user requests a protected resource.&lt;/li&gt;
&lt;li&gt;The application redirects the user to Keycloak's login page.&lt;/li&gt;
&lt;li&gt;After successful authentication, Keycloak redirects back with an authorization code.&lt;/li&gt;
&lt;li&gt;The application exchanges the code for &lt;strong&gt;access&lt;/strong&gt; and &lt;strong&gt;ID tokens&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The application validates the token and grants access.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example: Verifying a Token in Node.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jwksClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jwks-rsa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsonwebtoken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;jwksClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;jwksUri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8080/realms/myrealm/protocol/openid-connect/certs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSigningKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPublicKey&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;verifyToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;algorithms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RS256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Production Considerations
&lt;/h2&gt;

&lt;p&gt;When deploying Keycloak to production, keep these best practices in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use a proper database&lt;/strong&gt; (PostgreSQL, MySQL) instead of the dev default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable HTTPS/TLS&lt;/strong&gt; to protect tokens in transit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run in cluster mode&lt;/strong&gt; for high availability and horizontal scaling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure token lifespans&lt;/strong&gt; appropriately to balance security and UX.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set up regular backups&lt;/strong&gt; of your realm configuration and database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Harden the admin console&lt;/strong&gt; by restricting network access.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production Startup Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8443:8443 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgres &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_DB_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;jdbc:postgresql://db:5432/keycloak &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_DB_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;keycloak &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_DB_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;secret &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_HOSTNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;auth.example.com &lt;span class="se"&gt;\&lt;/span&gt;
  quay.io/keycloak/keycloak:latest &lt;span class="se"&gt;\&lt;/span&gt;
  start &lt;span class="nt"&gt;--optimized&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advantages and Trade-offs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free and open source with no licensing costs&lt;/li&gt;
&lt;li&gt;Standards-compliant, avoiding vendor lock-in&lt;/li&gt;
&lt;li&gt;Highly extensible via custom providers and SPIs&lt;/li&gt;
&lt;li&gt;Strong community and enterprise backing from Red Hat&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Trade-offs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requires operational effort to host and maintain&lt;/li&gt;
&lt;li&gt;Steeper learning curve compared to managed SaaS alternatives&lt;/li&gt;
&lt;li&gt;Scaling and upgrades demand careful planning&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Keycloak is a powerful, mature IAM solution that brings enterprise-grade authentication and authorization to any organization without licensing fees. By offloading identity management to a dedicated, standards-based platform, development teams can focus on building features rather than reinventing security infrastructure. While it requires operational commitment, the flexibility and control it offers make it an excellent choice for teams that want to own their identity stack.&lt;/p&gt;

</description>
      <category>keycloak</category>
      <category>iam</category>
      <category>security</category>
      <category>authentication</category>
    </item>
    <item>
      <title>PI Planning &amp; Strategic Alignment: How to Drive Roadmaps That Actually Deliver</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Tue, 25 Aug 2026 22:27:41 +0000</pubDate>
      <link>https://dev.to/said_olano/pi-planning-strategic-alignment-how-to-drive-roadmaps-that-actually-deliver-4i2l</link>
      <guid>https://dev.to/said_olano/pi-planning-strategic-alignment-how-to-drive-roadmaps-that-actually-deliver-4i2l</guid>
      <description>&lt;h1&gt;
  
  
  PI Planning &amp;amp; Strategic Alignment: How to Drive Roadmaps That Actually Deliver
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Keywords:&lt;/strong&gt; PI Planning, Program Increment, Agile Leadership, Stakeholder Management, SAFe, Strategic Alignment&lt;/p&gt;




&lt;h2&gt;
  
  
  The Challenge: Misaligned Roadmaps and Frustrated Stakeholders
&lt;/h2&gt;

&lt;p&gt;You've built great engineering teams. Your developers are shipping features. Your sprints are on track.&lt;/p&gt;

&lt;p&gt;But something's wrong.&lt;/p&gt;

&lt;p&gt;The roadmap your teams built doesn't match what your stakeholders expected. The features you're shipping don't align with business priorities. And by the time you realize it, you're three months in and the damage is done.&lt;/p&gt;

&lt;p&gt;This is the PI Planning problem.&lt;/p&gt;

&lt;p&gt;Program Increment (PI) Planning isn't just another meeting. It's where &lt;strong&gt;strategy becomes execution&lt;/strong&gt;, where &lt;strong&gt;business intent&lt;/strong&gt; meets &lt;strong&gt;technical reality&lt;/strong&gt;, and where &lt;strong&gt;stakeholder alignment&lt;/strong&gt; either happens or falls apart.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is PI Planning (And Why It Matters)
&lt;/h2&gt;

&lt;p&gt;PI Planning is a &lt;strong&gt;quarterly event&lt;/strong&gt; where the entire engineering organization—managers, architects, product leaders—aligns on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Business objectives for the next quarter&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Technical capabilities needed&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependencies across teams&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Realistic commitments&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Risk mitigation strategies&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Without PI Planning:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Teams build in silos&lt;/li&gt;
&lt;li&gt;Roadmaps drift from business goals&lt;/li&gt;
&lt;li&gt;Stakeholders are surprised by what ships&lt;/li&gt;
&lt;li&gt;Dependencies aren't discovered until mid-sprint&lt;/li&gt;
&lt;li&gt;Technical debt accumulates unchecked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;With strong PI Planning:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everyone knows why they're building what&lt;/li&gt;
&lt;li&gt;Business and engineering are aligned&lt;/li&gt;
&lt;li&gt;Dependencies are surfaced early&lt;/li&gt;
&lt;li&gt;Roadmaps stay predictable&lt;/li&gt;
&lt;li&gt;Technical decisions serve business goals&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Framework: How to Drive Effective PI Planning
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Phase 1: Pre-Planning (2 weeks before)
&lt;/h3&gt;

&lt;p&gt;Before the meeting, you do the homework:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Gather business context&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are this quarter's top 3-5 business priorities?&lt;/li&gt;
&lt;li&gt;Which customer problems are we solving?&lt;/li&gt;
&lt;li&gt;What revenue impact are we targeting?&lt;/li&gt;
&lt;li&gt;What competitive threats are we addressing?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Inventory current capabilities&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What's our actual capacity? (Don't guess—measure)&lt;/li&gt;
&lt;li&gt;What technical debt are we carrying?&lt;/li&gt;
&lt;li&gt;What's in flight from last quarter?&lt;/li&gt;
&lt;li&gt;What skills do our teams have?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Identify constraints&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are there hard dependencies on other teams?&lt;/li&gt;
&lt;li&gt;Do we need external resources?&lt;/li&gt;
&lt;li&gt;What infrastructure limitations exist?&lt;/li&gt;
&lt;li&gt;What regulatory or compliance issues matter?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Draft strategic themes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A strategic theme is a business-level objective that multiple teams contribute to.&lt;/p&gt;

&lt;p&gt;Example themes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Improve API response time by 50% (customer experience + competitive advantage)"&lt;/li&gt;
&lt;li&gt;"Reduce onboarding friction (customer retention + revenue growth)"&lt;/li&gt;
&lt;li&gt;"Build compliance reporting (regulatory requirement)"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each theme has a clear business outcome. Not a technical output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: The Planning Meeting (1 day, structured)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Morning: Context Setting (3 hours)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The business stakeholders present:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quarter strategy (15 min)&lt;/li&gt;
&lt;li&gt;Customer feedback (15 min)&lt;/li&gt;
&lt;li&gt;Competitive landscape (10 min)&lt;/li&gt;
&lt;li&gt;Success metrics (10 min)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the &lt;strong&gt;hardest part&lt;/strong&gt;: Open questions.&lt;/p&gt;

&lt;p&gt;Your engineering leadership asks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"If we only shipped 3 things this quarter, which would matter most?"&lt;/li&gt;
&lt;li&gt;"What's the minimum viable capability for each priority?"&lt;/li&gt;
&lt;li&gt;"Where do we need to invest in technical foundation vs. features?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where misalignment gets discovered. And &lt;strong&gt;better now than in August when stakeholders realize you built the wrong thing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Afternoon: Team Planning (3 hours)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams take the strategic themes and break them into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Features&lt;/strong&gt; (what customers see)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enablers&lt;/strong&gt; (technical foundation to support features)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure&lt;/strong&gt; (platform reliability and tools)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defect fixes&lt;/strong&gt; (bugs affecting customers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For each item, teams commit to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estimated capacity (stories, points, or t-shirt sizes)&lt;/li&gt;
&lt;li&gt;Dependencies (which other teams matter)&lt;/li&gt;
&lt;li&gt;Assumptions (what has to be true)&lt;/li&gt;
&lt;li&gt;Risks (what could go wrong)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The commitment is realistic. Not aspirational. Real.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: Roadmap Validation (Post-meeting)
&lt;/h3&gt;

&lt;p&gt;After the meeting, as the engineering leader, you do a final validation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Does the roadmap actually address the business priorities?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If not, realign immediately&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Are the dependencies manageable?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If Team A depends on Team B depends on Team C, that's risk&lt;/li&gt;
&lt;li&gt;Identify and mitigate early&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do we have the people and skills?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A plan that requires a skill you don't have is just fiction&lt;/li&gt;
&lt;li&gt;Identify training or hiring needs now&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What could derail us?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;External dependencies, unknown unknowns, team changes, technical surprises&lt;/li&gt;
&lt;li&gt;Plan for each&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Key to Success: Ruthless Prioritization
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable truth: &lt;strong&gt;You cannot do everything.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The best PIs don't have the most ambitious plans. They have the &lt;strong&gt;most ruthlessly prioritized&lt;/strong&gt; plans.&lt;/p&gt;

&lt;p&gt;I watched an organization plan to build 30 features in a quarter. They got 6 done. Another organization planned 8 features and delivered 8. Same engineering team, same capacity.&lt;/p&gt;

&lt;p&gt;The difference? The second organization said "no" to 90% of requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to prioritize ruthlessly:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use business impact as the primary filter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not "cool tech", not "customer niceness"&lt;/li&gt;
&lt;li&gt;Impact: revenue, retention, competitive advantage, risk mitigation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Apply the "drop-off" test&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rank your priorities 1-10&lt;/li&gt;
&lt;li&gt;Cut everything ranked 4+&lt;/li&gt;
&lt;li&gt;Focus on 1-3&lt;/li&gt;
&lt;li&gt;It's painful. That's the point.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Get stakeholder buy-in on the cuts&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If stakeholders don't agree with priorities, something's wrong&lt;/li&gt;
&lt;li&gt;Better to fight about it in planning than in August&lt;/li&gt;
&lt;li&gt;Build trust by saying "no" early&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Stakeholder Alignment: The Real Work
&lt;/h2&gt;

&lt;p&gt;PI Planning isn't just an engineering exercise. It's a &lt;strong&gt;stakeholder alignment ceremony.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your job as engineering leader is to make sure business leaders and engineering teams speak the same language about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are we building?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not "refactor the auth service"&lt;/li&gt;
&lt;li&gt;But "reduce login failures from 2% to 0.1% (improves retention by 5%)"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why are we building it?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not "to avoid technical debt"&lt;/li&gt;
&lt;li&gt;But "because customers report login frustration in NPS surveys"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What does success look like?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not "code is deployed"&lt;/li&gt;
&lt;li&gt;But "customers can reliably log in under 300ms, 99.9% uptime"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How do we know we're on track?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not "sprint velocity"&lt;/li&gt;
&lt;li&gt;But "weekly login success rate + customer satisfaction"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This translation between "business language" and "engineering language" is &lt;strong&gt;your job as the liaison between stakeholders and teams.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Common PI Planning Mistakes (And How to Avoid Them)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mistake 1: Overly Ambitious Planning
&lt;/h3&gt;

&lt;p&gt;You commit to 50 points worth of work. You always have 25 left over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Track your actual capacity. If you finish 25 points in a sprint, your capacity is 25. Plan for 20 (account for unknowns).&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 2: Ignoring Dependencies
&lt;/h3&gt;

&lt;p&gt;Team A builds Feature X. Team B builds Feature Y. They need each other. You didn't realize it until week 6.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Explicitly map dependencies. If Team A blocks Team B for 2 weeks, Team B plans for that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 3: Zero Technical Debt Work
&lt;/h3&gt;

&lt;p&gt;"We'll get to refactoring the database later."&lt;/p&gt;

&lt;p&gt;Later never comes. And that database becomes a crisis in Q4.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Allocate 20-30% of capacity to "enablers"—technical foundation, debt, infrastructure. It's not optional. It's survival.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 4: Forgetting About Incidents
&lt;/h3&gt;

&lt;p&gt;You plan a perfect quarter. Then a customer-critical bug appears. Your best engineers spend 2 weeks on it. The plan falls apart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Reserve 10-15% of capacity for "buffer"—unplanned incidents, urgent bugs, customer escalations. Not wasted capacity. Insurance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 5: No Stakeholder Participation
&lt;/h3&gt;

&lt;p&gt;Engineering teams plan alone. Then they show stakeholders the roadmap. Stakeholders hate it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Have stakeholders in the room during PI Planning. Conflict early, when it's cheap to fix. Not in August.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Example: Scaling Across Multiple Squads
&lt;/h2&gt;

&lt;p&gt;I led PI Planning for a 30-person engineering org (3 squads of 10). Here's what worked:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-Planning (Week 1-2):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product leadership: 3 business priorities&lt;/li&gt;
&lt;li&gt;Architecture: platform constraints and opportunities&lt;/li&gt;
&lt;li&gt;Each squad lead: realistic capacity assessment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Planning (Day 1 - Morning):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business leader: "This quarter we're improving payment reliability (15% of failed transactions) and reducing onboarding time"&lt;/li&gt;
&lt;li&gt;Architecture: "We need to migrate off the legacy payment system (3-week project)"&lt;/li&gt;
&lt;li&gt;Finance: "New regulatory requirement for audit logging"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Planning (Day 1 - Afternoon):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Squad 1: "We'll own the payment migration + regulatory logging"&lt;/li&gt;
&lt;li&gt;Squad 2: "We'll own onboarding UX improvements + APIs"&lt;/li&gt;
&lt;li&gt;Squad 3: "We'll own internal tools + technical debt"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Post-Planning:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reality check: All dependencies documented, capacity matches reality&lt;/li&gt;
&lt;li&gt;Dependencies surfaced: Squad 2 needs Squad 1's API changes by week 3&lt;/li&gt;
&lt;li&gt;Risk: Payment system provider outage during migration. Plan: dual-deployment approach&lt;/li&gt;
&lt;li&gt;Validation: All 3 business priorities addressed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment reliability improved 40% (saved $500K in chargebacks)&lt;/li&gt;
&lt;li&gt;Onboarding time reduced by 30% (boosted conversion)&lt;/li&gt;
&lt;li&gt;Technical debt halved (reduced future incidents)&lt;/li&gt;
&lt;li&gt;All three squads hit their commitments&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Measuring Success: Beyond Velocity
&lt;/h2&gt;

&lt;p&gt;You'll know PI Planning is working when:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Stakeholders understand the roadmap&lt;/strong&gt; - Not because you told them again, but because they helped build it&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Roadmaps stay stable&lt;/strong&gt; - 80%+ of PI committed work actually ships&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Dependencies are surfaced early&lt;/strong&gt; - Problems discovered in planning, not mid-sprint&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Technical debt gets addressed&lt;/strong&gt; - Enablers are 20-30% of capacity&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Business outcomes materialize&lt;/strong&gt; - Features shipped actually move the needle&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Teams feel ownership&lt;/strong&gt; - Engineers understand why they're building&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;PI Planning isn't about processes or ceremonies. It's about &lt;strong&gt;creating alignment&lt;/strong&gt; between what business needs and what engineering builds.&lt;/p&gt;

&lt;p&gt;When PI Planning works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engineers aren't surprised by pivots&lt;/li&gt;
&lt;li&gt;Stakeholders aren't surprised by delays&lt;/li&gt;
&lt;li&gt;Business outcomes improve&lt;/li&gt;
&lt;li&gt;Teams feel ownership&lt;/li&gt;
&lt;li&gt;Technical foundation stays healthy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When PI Planning doesn't happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Roadmaps drift&lt;/li&gt;
&lt;li&gt;Stakeholders are frustrated&lt;/li&gt;
&lt;li&gt;Teams are frustrated&lt;/li&gt;
&lt;li&gt;Technical debt explodes&lt;/li&gt;
&lt;li&gt;Quarters feel chaotic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The investment? One intense day every quarter.&lt;/p&gt;

&lt;p&gt;The return? A quarter of coordinated, aligned, high-impact engineering.&lt;/p&gt;

&lt;p&gt;That's the trade. And it's worth it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Your Action Items
&lt;/h2&gt;

&lt;p&gt;This quarter:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Gather your stakeholders&lt;/strong&gt; - What are the 3-5 business priorities? What constraints exist?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set capacity realistically&lt;/strong&gt; - Don't guess. Measure. Look at last quarter's actual throughput.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Map dependencies&lt;/strong&gt; - Which teams need to coordinate? What's the critical path?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run PI Planning&lt;/strong&gt; - Half-day: Stakeholders present. Half-day: Teams plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communicate the roadmap&lt;/strong&gt; - Not just the what, but the why and the how.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;The best quarter isn't the busiest one. It's the most aligned one.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PI Planning makes that alignment happen.&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>agile</category>
      <category>productmanagement</category>
      <category>roadmap</category>
    </item>
    <item>
      <title>PI Planning &amp; Strategic Alignment: Driving Roadmaps That Deliver</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Tue, 25 Aug 2026 22:25:41 +0000</pubDate>
      <link>https://dev.to/said_olano/pi-planning-strategic-alignment-driving-roadmaps-that-deliver-c0j</link>
      <guid>https://dev.to/said_olano/pi-planning-strategic-alignment-driving-roadmaps-that-deliver-c0j</guid>
      <description>&lt;h1&gt;
  
  
  PI Planning &amp;amp; Strategic Alignment: Driving Roadmaps That Deliver
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Keywords:&lt;/strong&gt; PI Planning, Program Increment, Agile Leadership, Stakeholder Management, SAFe, Strategic Alignment&lt;/p&gt;




&lt;h2&gt;
  
  
  The Challenge: Misaligned Roadmaps and Frustrated Stakeholders
&lt;/h2&gt;

&lt;p&gt;You've built great engineering teams. Your developers are shipping features. Your sprints are on track.&lt;/p&gt;

&lt;p&gt;But something's wrong.&lt;/p&gt;

&lt;p&gt;The roadmap your teams built doesn't match what your stakeholders expected. The features you're shipping don't align with business priorities. And by the time you realize it, you're three months in and the damage is done.&lt;/p&gt;

&lt;p&gt;This is the PI Planning problem.&lt;/p&gt;

&lt;p&gt;Program Increment (PI) Planning isn't just another meeting. It's where &lt;strong&gt;strategy becomes execution&lt;/strong&gt;, where &lt;strong&gt;business intent&lt;/strong&gt; meets &lt;strong&gt;technical reality&lt;/strong&gt;, and where &lt;strong&gt;stakeholder alignment&lt;/strong&gt; either happens or falls apart.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is PI Planning (And Why It Matters)
&lt;/h2&gt;

&lt;p&gt;PI Planning is a &lt;strong&gt;quarterly event&lt;/strong&gt; where the entire engineering organization—managers, architects, product leaders—aligns on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Business objectives for the next quarter&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Technical capabilities needed&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependencies across teams&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Realistic commitments&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Risk mitigation strategies&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Without PI Planning:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Teams build in silos&lt;/li&gt;
&lt;li&gt;Roadmaps drift from business goals&lt;/li&gt;
&lt;li&gt;Stakeholders are surprised by what ships&lt;/li&gt;
&lt;li&gt;Dependencies aren't discovered until mid-sprint&lt;/li&gt;
&lt;li&gt;Technical debt accumulates unchecked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;With strong PI Planning:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everyone knows why they're building what&lt;/li&gt;
&lt;li&gt;Business and engineering are aligned&lt;/li&gt;
&lt;li&gt;Dependencies are surfaced early&lt;/li&gt;
&lt;li&gt;Roadmaps stay predictable&lt;/li&gt;
&lt;li&gt;Technical decisions serve business goals&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Framework: How to Drive Effective PI Planning
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Phase 1: Pre-Planning (2 weeks before)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before the meeting, you do the homework:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Gather business context&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are this quarter's top 3-5 business priorities?&lt;/li&gt;
&lt;li&gt;Which customer problems are we solving?&lt;/li&gt;
&lt;li&gt;What revenue impact are we targeting?&lt;/li&gt;
&lt;li&gt;What competitive threats are we addressing?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Inventory current capabilities&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What's our actual capacity? (Don't guess—measure)&lt;/li&gt;
&lt;li&gt;What technical debt are we carrying?&lt;/li&gt;
&lt;li&gt;What's in flight from last quarter?&lt;/li&gt;
&lt;li&gt;What skills do our teams have?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Identify constraints&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are there hard dependencies on other teams?&lt;/li&gt;
&lt;li&gt;Do we need external resources?&lt;/li&gt;
&lt;li&gt;What infrastructure limitations exist?&lt;/li&gt;
&lt;li&gt;What regulatory or compliance issues matter?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Draft strategic themes&lt;/strong&gt;&lt;br&gt;
A strategic theme is a business-level objective that multiple teams contribute to.&lt;/p&gt;

&lt;p&gt;Example themes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Improve API response time by 50% (customer experience + competitive advantage)"&lt;/li&gt;
&lt;li&gt;"Reduce onboarding friction (customer retention + revenue growth)"&lt;/li&gt;
&lt;li&gt;"Build compliance reporting (regulatory requirement)"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each theme has a clear business outcome. Not a technical output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: The Planning Meeting (1 day, structured)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Morning: Context Setting (3 hours)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The business stakeholders present:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quarter strategy (15 min)&lt;/li&gt;
&lt;li&gt;Customer feedback (15 min)&lt;/li&gt;
&lt;li&gt;Competitive landscape (10 min)&lt;/li&gt;
&lt;li&gt;Success metrics (10 min)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the &lt;strong&gt;hardest part&lt;/strong&gt;: Open questions.&lt;/p&gt;

&lt;p&gt;Your engineering leadership asks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"If we only shipped 3 things this quarter, which would matter most?"&lt;/li&gt;
&lt;li&gt;"What's the minimum viable capability for each priority?"&lt;/li&gt;
&lt;li&gt;"Where do we need to invest in technical foundation vs. features?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where misalignment gets discovered. And &lt;strong&gt;better now than in August when stakeholders realize you built the wrong thing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Afternoon: Team Planning (3 hours)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams take the strategic themes and break them into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Features&lt;/strong&gt; (what customers see)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enablers&lt;/strong&gt; (technical foundation to support features)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure&lt;/strong&gt; (platform reliability and tools)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defect fixes&lt;/strong&gt; (bugs affecting customers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For each item, teams commit to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Estimated capacity&lt;/strong&gt; (stories, points, or t-shirt sizes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies&lt;/strong&gt; (which other teams matter)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assumptions&lt;/strong&gt; (what has to be true)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risks&lt;/strong&gt; (what could go wrong)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The commitment is realistic. Not aspirational. Real.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: Roadmap Validation (Post-meeting)
&lt;/h3&gt;

&lt;p&gt;After the meeting, as the engineering leader, you do a final validation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Does the roadmap actually address the business priorities?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If not, realign immediately&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Are the dependencies manageable?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If Team A depends on Team B depends on Team C, that's risk&lt;/li&gt;
&lt;li&gt;Identify and mitigate early&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do we have the people and skills?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A plan that requires a skill you don't have is just fiction&lt;/li&gt;
&lt;li&gt;Identify training or hiring needs now&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What could derail us?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;External dependencies&lt;/li&gt;
&lt;li&gt;Unknown unknowns&lt;/li&gt;
&lt;li&gt;Team changes&lt;/li&gt;
&lt;li&gt;Technical surprises&lt;/li&gt;
&lt;li&gt;Plan for each&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Key to Success: Ruthless Prioritization
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable truth:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You cannot do everything.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The best PIs don't have the most ambitious plans. They have the &lt;strong&gt;most ruthlessly prioritized&lt;/strong&gt; plans.&lt;/p&gt;

&lt;p&gt;I watched an organization plan to build 30 features in a quarter. They got 6 done. Another organization planned 8 features and delivered 8. Same engineering team, same capacity.&lt;/p&gt;

&lt;p&gt;The difference? The second organization said "no" to 90% of requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to prioritize ruthlessly:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use business impact as the primary filter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not "cool tech"&lt;/li&gt;
&lt;li&gt;Not "customer niceness"&lt;/li&gt;
&lt;li&gt;Impact: revenue, retention, competitive advantage, risk mitigation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Apply the "drop-off" test&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rank your priorities 1-10&lt;/li&gt;
&lt;li&gt;Cut everything ranked 4+&lt;/li&gt;
&lt;li&gt;Focus on 1-3&lt;/li&gt;
&lt;li&gt;It's painful. That's the point.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Get stakeholder buy-in on the cuts&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If stakeholders don't agree with priorities, something's wrong&lt;/li&gt;
&lt;li&gt;Better to fight about it in planning than in August&lt;/li&gt;
&lt;li&gt;Build trust by saying "no" early&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Stakeholder Alignment: The Real Work
&lt;/h2&gt;

&lt;p&gt;PI Planning isn't just an engineering exercise. It's a &lt;strong&gt;stakeholder alignment ceremony.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your job as engineering leader is to make sure business leaders and engineering teams speak the same language about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are we building?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not "refactor the auth service"&lt;/li&gt;
&lt;li&gt;But "reduce login failures from 2% to 0.1% (improves retention by 5%)"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why are we building it?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not "to avoid technical debt"&lt;/li&gt;
&lt;li&gt;But "because customers report login frustration in NPS surveys"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What does success look like?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not "code is deployed"&lt;/li&gt;
&lt;li&gt;But "customers can reliably log in under 300ms, 99.9% uptime"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How do we know we're on track?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not "sprint velocity"&lt;/li&gt;
&lt;li&gt;But "weekly login success rate + customer satisfaction"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This translation between "business language" and "engineering language" is &lt;strong&gt;your job as the liaison between stakeholders and teams.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Common PI Planning Mistakes (And How to Avoid Them)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mistake 1: Overly Ambitious Planning
&lt;/h3&gt;

&lt;p&gt;You commit to 50 points worth of work. You always have 25 left over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Track your actual capacity. If you finish 25 points in a sprint, your capacity is 25. Plan for 20 (account for unknowns). That's a successful PI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 2: Ignoring Dependencies
&lt;/h3&gt;

&lt;p&gt;Team A builds Feature X. Team B builds Feature Y. They need each other. You didn't realize it until week 6.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; In planning, explicitly map dependencies. If Team A blocks Team B for 2 weeks, Team B plans for that. Better than discovering it mid-quarter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 3: Zero Technical Debt Work
&lt;/h3&gt;

&lt;p&gt;"We'll get to refactoring the database later."&lt;/p&gt;

&lt;p&gt;Later never comes. And that database becomes a crisis in Q4.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Allocate 20-30% of capacity to "enablers"—technical foundation, debt, infrastructure. It's not optional. It's survival.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 4: Forgetting About Incidents
&lt;/h3&gt;

&lt;p&gt;You plan a perfect quarter. Then a customer-critical bug appears. Your best engineers spend 2 weeks on it. The plan falls apart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Reserve 10-15% of capacity for "buffer"—unplanned incidents, urgent bugs, customer escalations. Not wasted capacity. Insurance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 5: No Stakeholder Participation
&lt;/h3&gt;

&lt;p&gt;Engineering teams plan alone. Then they show stakeholders the roadmap.&lt;/p&gt;

&lt;p&gt;Stakeholders hate it. It doesn't match their priorities. You replan. Twice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Have stakeholders in the room during PI Planning. Conflict early, when it's cheap to fix. Not in August.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Example: Scaling Across Multiple Squads
&lt;/h2&gt;

&lt;p&gt;I led PI Planning for a 30-person engineering org (3 squads of 10). Here's what worked:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-Planning (Week 1-2):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product leadership: 3 business priorities&lt;/li&gt;
&lt;li&gt;Architecture: platform constraints and opportunities&lt;/li&gt;
&lt;li&gt;Each squad lead: realistic capacity assessment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Planning (Day 1 - Morning):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business leader: "This quarter we're improving payment reliability (15% of failed transactions) and reducing onboarding time (critical for Q4 launches)"&lt;/li&gt;
&lt;li&gt;Architecture: "We need to migrate off the legacy payment system (3-week project)"&lt;/li&gt;
&lt;li&gt;Finance: "New regulatory requirement for audit logging"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Planning (Day 1 - Afternoon):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Squad 1: "We'll own the payment migration + regulatory logging"&lt;/li&gt;
&lt;li&gt;Squad 2: "We'll own onboarding UX improvements + APIs"&lt;/li&gt;
&lt;li&gt;Squad 3: "We'll own internal tools + technical debt"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Post-Planning:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reality check: Migration is 3 weeks, leaves 3 weeks for enhancements. Onboarding can land 2 features + 1 research spike. Tools team can refactor the data layer.&lt;/li&gt;
&lt;li&gt;Dependencies surfaced: Squad 2 needs Squad 1's API changes by week 3. Squad 3 needs data layer before Squad 2 can optimize queries.&lt;/li&gt;
&lt;li&gt;Risk: Payment system provider outage during migration. Plan: partner with Platform team, dual-deployment approach.&lt;/li&gt;
&lt;li&gt;Validation: All 3 business priorities are addressed. All dependencies are documented. Capacity matches reality.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment reliability improved 40% (saved $500K in chargebacks)&lt;/li&gt;
&lt;li&gt;Onboarding time reduced by 30% (boosted conversion)&lt;/li&gt;
&lt;li&gt;Technical debt halved (reduced future incidents)&lt;/li&gt;
&lt;li&gt;All three squads hit their commitments&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Measuring Success: Beyond Velocity
&lt;/h2&gt;

&lt;p&gt;You'll know PI Planning is working when:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Stakeholders understand the roadmap&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not because you told them again&lt;/li&gt;
&lt;li&gt;But because they helped build it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Roadmaps stay stable&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;80%+ of PI committed work actually ships&lt;/li&gt;
&lt;li&gt;Surprises are rare&lt;/li&gt;
&lt;li&gt;Plans adjust, but rarely pivot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Dependencies are surfaced early&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Problems discovered in planning, not mid-sprint&lt;/li&gt;
&lt;li&gt;Handoffs are smooth&lt;/li&gt;
&lt;li&gt;Teams can explain why they depend on each other&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Technical debt gets addressed&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enablers are 20-30% of capacity&lt;/li&gt;
&lt;li&gt;Infrastructure investments happen&lt;/li&gt;
&lt;li&gt;Technical health improves quarter over quarter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Business outcomes materialize&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Features shipped actually move the needle&lt;/li&gt;
&lt;li&gt;Stakeholders see ROI&lt;/li&gt;
&lt;li&gt;Customers notice improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Teams feel ownership&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engineers understand why they're building&lt;/li&gt;
&lt;li&gt;Squads commit to realistic goals&lt;/li&gt;
&lt;li&gt;Celebrations happen when milestones hit&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;PI Planning isn't about processes or ceremonies. It's about &lt;strong&gt;creating alignment&lt;/strong&gt; between what business needs and what engineering builds.&lt;/p&gt;

&lt;p&gt;When PI Planning works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engineers aren't surprised by pivots&lt;/li&gt;
&lt;li&gt;Stakeholders aren't surprised by delays&lt;/li&gt;
&lt;li&gt;Business outcomes improve&lt;/li&gt;
&lt;li&gt;Teams feel ownership&lt;/li&gt;
&lt;li&gt;Technical foundation stays healthy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When PI Planning doesn't happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Roadmaps drift&lt;/li&gt;
&lt;li&gt;Stakeholders are frustrated&lt;/li&gt;
&lt;li&gt;Teams are frustrated&lt;/li&gt;
&lt;li&gt;Technical debt explodes&lt;/li&gt;
&lt;li&gt;Quarters feel chaotic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The investment? One intense day every quarter.&lt;/p&gt;

&lt;p&gt;The return? A quarter of coordinated, aligned, high-impact engineering.&lt;/p&gt;

&lt;p&gt;That's the trade. And it's worth it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Your Action Items
&lt;/h2&gt;

&lt;p&gt;This quarter:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gather your stakeholders&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are the 3-5 business priorities?&lt;/li&gt;
&lt;li&gt;What constraints exist?&lt;/li&gt;
&lt;li&gt;What's the one metric we should optimize for?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set capacity realistically&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't guess. Measure.&lt;/li&gt;
&lt;li&gt;Look at last quarter's actual throughput&lt;/li&gt;
&lt;li&gt;Factor in buffer (10-15%) for unknowns&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Map dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which teams need to coordinate?&lt;/li&gt;
&lt;li&gt;What's the critical path?&lt;/li&gt;
&lt;li&gt;What could block us?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Run PI Planning&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Half-day: Stakeholders present&lt;/li&gt;
&lt;li&gt;Half-day: Teams plan&lt;/li&gt;
&lt;li&gt;Follow-up: Validation and de-risking&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Communicate the roadmap&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not just the what (features)&lt;/li&gt;
&lt;li&gt;But the why (business outcomes)&lt;/li&gt;
&lt;li&gt;And the how (dependencies, risks, assumptions)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;The best quarter isn't the busiest one. It's the most aligned one.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PI Planning makes that alignment happen.&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>agile</category>
      <category>productmanagement</category>
      <category>roadmap</category>
    </item>
    <item>
      <title>AWS S3: Storage Strategy and Best Practices (2026-08-25 22:14)</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Tue, 25 Aug 2026 22:14:17 +0000</pubDate>
      <link>https://dev.to/said_olano/aws-s3-storage-strategy-and-best-practices-2026-08-25-2214-4he7</link>
      <guid>https://dev.to/said_olano/aws-s3-storage-strategy-and-best-practices-2026-08-25-2214-4he7</guid>
      <description>&lt;h1&gt;
  
  
  AWS S3: Storage Strategy and Best Practices
&lt;/h1&gt;

&lt;p&gt;Amazon Simple Storage Service (S3) is one of the foundational services in the AWS ecosystem. While it's easy to get started—create a bucket, upload an object—building a cost-effective, secure, and performant storage strategy requires deliberate planning. This post covers the practices that matter most in production environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding S3 Storage Classes
&lt;/h2&gt;

&lt;p&gt;Choosing the right storage class is the single most impactful decision for controlling cost. Each class trades off availability, retrieval latency, and price.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Storage Class&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Retrieval&lt;/th&gt;
&lt;th&gt;Min. Duration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S3 Standard&lt;/td&gt;
&lt;td&gt;Frequently accessed data&lt;/td&gt;
&lt;td&gt;Instant&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Intelligent-Tiering&lt;/td&gt;
&lt;td&gt;Unpredictable access patterns&lt;/td&gt;
&lt;td&gt;Instant&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Standard-IA&lt;/td&gt;
&lt;td&gt;Infrequent access, fast retrieval&lt;/td&gt;
&lt;td&gt;Instant&lt;/td&gt;
&lt;td&gt;30 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 One Zone-IA&lt;/td&gt;
&lt;td&gt;Infrequent, non-critical data&lt;/td&gt;
&lt;td&gt;Instant&lt;/td&gt;
&lt;td&gt;30 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Glacier Instant Retrieval&lt;/td&gt;
&lt;td&gt;Archives needing millisecond access&lt;/td&gt;
&lt;td&gt;Instant&lt;/td&gt;
&lt;td&gt;90 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Glacier Flexible Retrieval&lt;/td&gt;
&lt;td&gt;Archives, minutes to hours&lt;/td&gt;
&lt;td&gt;Minutes–hours&lt;/td&gt;
&lt;td&gt;90 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Glacier Deep Archive&lt;/td&gt;
&lt;td&gt;Long-term cold storage&lt;/td&gt;
&lt;td&gt;Up to 12 hours&lt;/td&gt;
&lt;td&gt;180 days&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Recommendation:&lt;/strong&gt; If your access patterns are unknown or variable, use &lt;strong&gt;S3 Intelligent-Tiering&lt;/strong&gt;. It automatically moves objects between tiers based on usage without retrieval fees, and the monitoring cost is negligible for most workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lifecycle Policies for Automated Cost Optimization
&lt;/h2&gt;

&lt;p&gt;Rather than manually managing object transitions, define lifecycle rules to automate them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ArchiveAndExpireLogs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"logs/"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enabled"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Transitions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"StorageClass"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STANDARD_IA"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"StorageClass"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GLACIER"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This rule keeps logs in Standard for 30 days, moves them to Standard-IA, then to Glacier, and finally deletes them after a year. Also configure &lt;code&gt;AbortIncompleteMultipartUpload&lt;/code&gt; to clean up failed uploads that silently accumulate storage costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Best Practices
&lt;/h2&gt;

&lt;p&gt;Security misconfigurations are the leading cause of S3 data exposure. Apply defense in depth.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Block Public Access
&lt;/h3&gt;

&lt;p&gt;Enable &lt;strong&gt;S3 Block Public Access&lt;/strong&gt; at both the account and bucket levels unless you have a documented reason to serve public content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api put-public-access-block &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; my-secure-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--public-access-block-configuration&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;BlockPublicAcls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,IgnorePublicAcls&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,BlockPublicPolicy&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,RestrictPublicBuckets&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Enforce Encryption
&lt;/h3&gt;

&lt;p&gt;Enable default encryption using SSE-KMS for sensitive data. Enforce it with a bucket policy that rejects unencrypted uploads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:PutObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-secure-bucket/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"StringNotEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"s3:x-amz-server-side-encryption"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"aws:kms"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Enforce TLS in Transit
&lt;/h3&gt;

&lt;p&gt;Deny any request not made over HTTPS using the &lt;code&gt;aws:SecureTransport&lt;/code&gt; condition key.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Least Privilege IAM
&lt;/h3&gt;

&lt;p&gt;Grant access via IAM roles scoped to specific prefixes and actions. Avoid wildcard &lt;code&gt;s3:*&lt;/code&gt; permissions and prefer bucket policies plus IAM over legacy ACLs (which AWS now disables by default).&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Durability and Protection
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enable Versioning&lt;/strong&gt; to protect against accidental deletion and overwrites. Combine it with lifecycle rules to expire old versions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable MFA Delete&lt;/strong&gt; on critical buckets to require multi-factor authentication for permanent deletions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Object Lock&lt;/strong&gt; in compliance mode for WORM (write-once-read-many) requirements such as audit logs and regulatory data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replicate critical data&lt;/strong&gt; using Cross-Region Replication (CRR) for disaster recovery or Same-Region Replication (SRR) for compliance and log aggregation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Performance Optimization
&lt;/h2&gt;

&lt;p&gt;S3 automatically scales to high request rates—3,500 PUT/COPY/POST/DELETE and 5,500 GET/HEAD requests per second &lt;strong&gt;per prefix&lt;/strong&gt;. To maximize throughput:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parallelize across prefixes.&lt;/strong&gt; Distributing objects across multiple prefixes multiplies your request ceiling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use multipart uploads&lt;/strong&gt; for objects larger than 100 MB to improve resilience and throughput.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable S3 Transfer Acceleration&lt;/strong&gt; for fast long-distance transfers over Amazon's edge network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Front frequently accessed content with CloudFront&lt;/strong&gt; to reduce latency and offload requests from S3.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Modern S3 no longer requires random hash prefixes for performance. The scaling is now automatic per prefix, so organize keys for logical clarity rather than performance hacks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cost Visibility and Monitoring
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Enable &lt;strong&gt;S3 Storage Lens&lt;/strong&gt; for account-wide visibility into usage and activity trends.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;cost allocation tags&lt;/strong&gt; to attribute spend to teams and projects.&lt;/li&gt;
&lt;li&gt;Set up &lt;strong&gt;S3 Inventory&lt;/strong&gt; reports to audit objects, encryption status, and replication&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>s3</category>
      <category>cloudstorage</category>
      <category>devops</category>
    </item>
    <item>
      <title>How Clear Performance Frameworks Beat Engineering Heroics Every Time</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Tue, 25 Aug 2026 21:49:14 +0000</pubDate>
      <link>https://dev.to/said_olano/how-clear-performance-frameworks-beat-engineering-heroics-every-time-2mfc</link>
      <guid>https://dev.to/said_olano/how-clear-performance-frameworks-beat-engineering-heroics-every-time-2mfc</guid>
      <description>&lt;h1&gt;
  
  
  How Clear Performance Frameworks Beat Engineering Heroics Every Time
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Keywords:&lt;/strong&gt; Engineering Leadership, Team Performance, Delivery Management, Sprint Management, Engineering Culture&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Chaos Disguised as High Performance
&lt;/h2&gt;

&lt;p&gt;When I took over my engineering teams, we had a productivity problem masquerading as "high performance."&lt;/p&gt;

&lt;p&gt;Teams were shipping features, sure. But the process was chaotic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sprint goals were vague narratives, not measurable outcomes&lt;/li&gt;
&lt;li&gt;Code commits were sporadic — bursts of activity followed by silence&lt;/li&gt;
&lt;li&gt;No one could predict when things would actually ship&lt;/li&gt;
&lt;li&gt;Developers worked long hours to meet artificial deadlines&lt;/li&gt;
&lt;li&gt;Burnout was creeping in, though no one said it out loud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The worst part? Leadership kept calling this "hustle culture" and "heroic delivery." &lt;/p&gt;

&lt;p&gt;I realized we had confused &lt;strong&gt;motion with momentum&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Turning Point: Getting Boring
&lt;/h2&gt;

&lt;p&gt;The breakthrough came when I stopped looking for heroics and started building systems.&lt;/p&gt;

&lt;p&gt;Here's what happened:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Defined What "Done" Actually Means
&lt;/h3&gt;

&lt;p&gt;Before: "Sprint goal: deliver the user profile feature"&lt;br&gt;
After: Clear Definition of Done (DoD)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ Code passes peer review (minimum 2 approvals)
✓ Unit tests pass (minimum 80% coverage)
✓ Integration tests pass on staging
✓ Code is merged to main branch
✓ Feature is deployable (not just developed)
✓ Documentation updated or created
✓ No known bugs or technical debt added
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple document transformed everything. Teams stopped debating what "done" meant. No more surprises at sprint review.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Established Sprint Goal Criteria
&lt;/h3&gt;

&lt;p&gt;Every sprint, we asked three questions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Is the goal measurable?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Bad: "Improve API performance"&lt;/li&gt;
&lt;li&gt;✅ Good: "Reduce API p99 latency from 500ms to 200ms"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Can it be verified by sprint end?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Bad: "Start the refactor"&lt;/li&gt;
&lt;li&gt;✅ Good: "Complete refactoring of payment service, all tests passing"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Does it deliver customer value or reduce risk?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Bad: "Upgrade libraries"&lt;/li&gt;
&lt;li&gt;✅ Good: "Patch critical security vulnerability in dependency, no breaking changes"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Teams went from vague aspirations to &lt;strong&gt;clear, achievable outcomes&lt;/strong&gt;. Sprint planning became 30 minutes instead of 2 hours of circular discussion.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Tracked Code Commit Cadence
&lt;/h3&gt;

&lt;p&gt;This was the big one: &lt;strong&gt;steady code flow, not panic pushes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We implemented daily commit tracking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Metrics we tracked:
- Commits per day per team member (target: 1-2)
- Commits per day per team (target: 8-12 for a 4-5 person team)
- Days without commits (target: max 1 per week)
- Commit message quality (linked to story, clear description)
- Code review turnaround (target: &amp;lt;24 hours)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What changed immediately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Predictability skyrocketed&lt;/strong&gt; — We could see progress in real time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Work-in-progress bottlenecks disappeared&lt;/strong&gt; — Commits flowing daily meant reviews weren't stacking up&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality improved&lt;/strong&gt; — Smaller commits are easier to review and less likely to introduce bugs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer confidence went up&lt;/strong&gt; — They could see their work moving forward&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The commit cadence became our &lt;strong&gt;heartbeat&lt;/strong&gt;. Missing a day wasn't catastrophic, but a pattern of inactivity meant we had a blocker to resolve.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Set Transparent Expectations
&lt;/h3&gt;

&lt;p&gt;Every team member got a simple document:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Performance Expectations for Engineering Teams&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are performing well if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your sprint goals are achieved 85%+ of the time&lt;/li&gt;
&lt;li&gt;Your team ships consistently within estimated complexity&lt;/li&gt;
&lt;li&gt;You contribute meaningful code commits 4-5 times per week&lt;/li&gt;
&lt;li&gt;Your pull requests get reviewed within 24 hours&lt;/li&gt;
&lt;li&gt;You're mentoring or being mentored on something challenging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;We help if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sprint goals slip repeatedly (we remove blockers together)&lt;/li&gt;
&lt;li&gt;Code reviews are stalling (we improve process)&lt;/li&gt;
&lt;li&gt;You're stuck on a problem (pair programming, research time)&lt;/li&gt;
&lt;li&gt;You feel overwhelmed (we rebalance work)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;No surprises. No hidden criteria. No "performance evaluation" that comes out of nowhere in July.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Results (In Numbers)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before the frameworks:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sprint goal attainment: ~60%&lt;/li&gt;
&lt;li&gt;Code review turnaround: 2-3 days&lt;/li&gt;
&lt;li&gt;Bug escape rate: 12% (bugs found in production)&lt;/li&gt;
&lt;li&gt;Developer satisfaction: 6.2/10&lt;/li&gt;
&lt;li&gt;Unplanned overtime: 15-20 hours/week (team-wide)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After implementing frameworks (3 months):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sprint goal attainment: 88%&lt;/li&gt;
&lt;li&gt;Code review turnaround: 12-18 hours&lt;/li&gt;
&lt;li&gt;Bug escape rate: 3%&lt;/li&gt;
&lt;li&gt;Developer satisfaction: 8.1/10&lt;/li&gt;
&lt;li&gt;Unplanned overtime: 2-3 hours/week (team-wide)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The financial impact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;3 fewer critical incidents per quarter&lt;/strong&gt; (no heroic firefighting = less context switching)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;40% faster feature time-to-market&lt;/strong&gt; (predictable velocity = better planning)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero unplanned quits&lt;/strong&gt; (clarity and consistency matter)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Works (The Psychology)
&lt;/h2&gt;

&lt;p&gt;Humans thrive under &lt;strong&gt;clarity, consistency, and control&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clarity&lt;/strong&gt; — "I know what success looks like"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt; — "I know what to expect every day"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control&lt;/strong&gt; — "I have agency in reaching the goal"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Performance frameworks give all three.&lt;/p&gt;

&lt;p&gt;When developers know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✓ What done means&lt;/li&gt;
&lt;li&gt;✓ What the sprint goal is&lt;/li&gt;
&lt;li&gt;✓ How their work will be reviewed&lt;/li&gt;
&lt;li&gt;✓ What performance looks like&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They don't need heroics. They just need to show up and do the work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mistake Most Teams Make
&lt;/h2&gt;

&lt;p&gt;"We don't need frameworks — our team is smart and self-organizing."&lt;/p&gt;

&lt;p&gt;I get it. Frameworks sound bureaucratic. But here's the truth:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-organization without frameworks is just chaos.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The best teams I've worked with had &lt;strong&gt;tight systems and clear guidelines&lt;/strong&gt;, not loose collaboration and "vibes."&lt;/p&gt;

&lt;p&gt;Think about sports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ No playbook, just "go out there and play hard"&lt;/li&gt;
&lt;li&gt;✅ Clear plays, positions, metrics, and objectives&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Engineering is the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation Checklist: Start This Week
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Week 1: Definition of Done
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Gather your team (1 hour)&lt;/li&gt;
&lt;li&gt;[ ] Ask: "What does 'done' mean to us?"&lt;/li&gt;
&lt;li&gt;[ ] Write it down (8-10 criteria)&lt;/li&gt;
&lt;li&gt;[ ] Make it visible (Slack, Confluence, somewhere everyone sees it)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Week 2: Sprint Goal Criteria
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Draft the "measurable, verifiable, valuable" template&lt;/li&gt;
&lt;li&gt;[ ] Retrospective: Review last 3 sprint goals through this lens&lt;/li&gt;
&lt;li&gt;[ ] Use it for next sprint planning&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Week 3: Commit Tracking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Set up a simple dashboard (GitHub, GitLab, or manual tracking)&lt;/li&gt;
&lt;li&gt;[ ] Track daily commits per person, per team&lt;/li&gt;
&lt;li&gt;[ ] Report in standup (30 seconds)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Week 4: Transparent Expectations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Write a 1-page "Performance Expectations" doc&lt;/li&gt;
&lt;li&gt;[ ] Share it with your team&lt;/li&gt;
&lt;li&gt;[ ] Use it for 1:1s and feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Time investment:&lt;/strong&gt; 4-6 hours upfront. &lt;strong&gt;Time savings:&lt;/strong&gt; 10-15 hours per week in clarification, rework, and firefighting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens Next
&lt;/h2&gt;

&lt;p&gt;Once you have frameworks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sprint planning becomes predictable&lt;/strong&gt; — You're not starting from zero each sprint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team confidence goes up&lt;/strong&gt; — Everyone knows what success looks like&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code quality improves&lt;/strong&gt; — Clear expectations drive consistent standards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Morale improves&lt;/strong&gt; — No surprises, no "heroic all-nighters"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turnover drops&lt;/strong&gt; — Clarity and consistency reduce burnout&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leadership gets visibility&lt;/strong&gt; — You can see progress in real time&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Real Secret
&lt;/h2&gt;

&lt;p&gt;High-performing teams don't work harder. They work smarter.&lt;/p&gt;

&lt;p&gt;And they work smarter because &lt;strong&gt;someone invested time in clarity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not complex frameworks. Not heavyweight processes.&lt;/p&gt;

&lt;p&gt;Just:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One clear definition of done&lt;/li&gt;
&lt;li&gt;Measurable sprint goals&lt;/li&gt;
&lt;li&gt;Visible progress tracking&lt;/li&gt;
&lt;li&gt;Transparent expectations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;The irony? The teams that implement these frameworks often look "boring" from the outside. No drama, no late-night commits, no "we shipped despite impossible odds" stories.&lt;/p&gt;

&lt;p&gt;Just consistent delivery. Week after week.&lt;/p&gt;

&lt;p&gt;And that's exactly the point.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What performance challenge is your team facing right now?&lt;/strong&gt; Drop a comment — I'd love to share more specific tactics based on what you're working with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read more:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to"&gt;Why Your Sprint Planning Fails (And How to Fix It)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to"&gt;The Myth of the 10x Developer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to"&gt;Building a Culture of Accountability Without Micromanagement&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  engineering #leadership #agile #devops #teammanagement #javadeveloper #softwarearchitecture
&lt;/h1&gt;

</description>
      <category>engineering</category>
      <category>leadership</category>
      <category>agile</category>
      <category>teammanagement</category>
    </item>
    <item>
      <title>Metro Web Services: High-Performance SOAP (2026-08-25 18:44)</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Tue, 25 Aug 2026 18:44:09 +0000</pubDate>
      <link>https://dev.to/said_olano/metro-web-services-high-performance-soap-2026-08-25-1844-479d</link>
      <guid>https://dev.to/said_olano/metro-web-services-high-performance-soap-2026-08-25-1844-479d</guid>
      <description>&lt;h1&gt;
  
  
  Metro Web Services: High-Performance SOAP
&lt;/h1&gt;

&lt;p&gt;While REST dominates modern API design, SOAP remains firmly entrenched in enterprise systems—particularly in finance, healthcare, telecommunications, and government sectors where contract-first design, strong typing, and standardized security matter. When you need SOAP on the Java platform, &lt;strong&gt;Metro&lt;/strong&gt; is one of the most capable and performant stacks available.&lt;/p&gt;

&lt;p&gt;This post explores what Metro is, how to build high-performance SOAP services with it, and the tuning strategies that separate a sluggish endpoint from a production-grade one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Metro?
&lt;/h2&gt;

&lt;p&gt;Metro is a comprehensive web services stack that combines two major components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JAX-WS (Jakarta XML Web Services)&lt;/strong&gt; — the reference implementation of the Java API for XML-based web services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WSIT (Web Services Interoperability Technologies)&lt;/strong&gt; — support for WS-* standards like WS-Security, WS-ReliableMessaging, WS-AtomicTransaction, and WS-Policy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together they provide a full-featured, standards-compliant SOAP platform that interoperates cleanly with .NET (WCF) and other WS-* implementations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up a Basic Service
&lt;/h2&gt;

&lt;p&gt;Metro embraces a &lt;strong&gt;contract-first&lt;/strong&gt; or &lt;strong&gt;code-first&lt;/strong&gt; approach. Here's a minimal code-first service endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.jws.WebService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.jws.WebMethod&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@WebService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"QuoteService"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QuoteService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@WebMethod&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;getQuote&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;shares&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;pricePerShare&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lookupPrice&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pricePerShare&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;shares&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;lookupPrice&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// lookup logic&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;142.75&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Publishing it for a quick test is trivial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.xml.ws.Endpoint&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Publisher&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Endpoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;publish&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"http://localhost:8080/quotes"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QuoteService&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Metro auto-generates the WSDL, available at &lt;code&gt;http://localhost:8080/quotes?wsdl&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Performance Challenge
&lt;/h2&gt;

&lt;p&gt;SOAP's reputation for being "slow" is largely a matter of configuration. The primary bottlenecks are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;XML parsing and serialization&lt;/strong&gt; overhead&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JAXB (un)marshalling&lt;/strong&gt; of large object graphs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verbose message payloads&lt;/strong&gt; consuming bandwidth&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Repeated schema validation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security processing&lt;/strong&gt; (signing, encryption)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Metro provides mechanisms to address each of these.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization 1: Fast Infoset
&lt;/h2&gt;

&lt;p&gt;The single biggest win for high-throughput scenarios is &lt;strong&gt;Fast Infoset (FI)&lt;/strong&gt;—a binary encoding of XML that dramatically reduces message size and parse time. When both client and server support it, Metro negotiates FI automatically via content negotiation.&lt;/p&gt;

&lt;p&gt;Enable it on the client via the &lt;code&gt;FastInfosetFeature&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.sun.xml.ws.developer.FastInfosetFeature&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;QuoteService&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;QuoteService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FastInfosetFeature&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or through a system property for pessimistic negotiation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"com.sun.xml.ws.client.ContentNegotiation"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"optimistic"&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In benchmarks with document-heavy payloads, Fast Infoset commonly reduces payload size by &lt;strong&gt;40–60%&lt;/strong&gt; and parse time by a similar margin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization 2: MTOM for Binary Data
&lt;/h2&gt;

&lt;p&gt;If your service transfers binary content (images, PDFs, documents), base64-encoding it inline bloats messages by ~33%. &lt;strong&gt;MTOM (Message Transmission Optimization Mechanism)&lt;/strong&gt; streams binary attachments alongside the SOAP envelope instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.xml.ws.soap.MTOM&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@MTOM&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@WebService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"DocumentService"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DocumentService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@WebMethod&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;fetchDocument&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;loadBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;threshold&lt;/code&gt; attribute means only payloads above 1 KB use MTOM optimization—small values stay inline to avoid attachment overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization 3: HTTP Persistent Connections and Streaming
&lt;/h2&gt;

&lt;p&gt;Metro's stream-based architecture avoids buffering entire messages in memory where possible. On the client, reuse the &lt;code&gt;Service&lt;/code&gt; and port instances—they're expensive to create but safe to reuse across threads when configured properly.&lt;/p&gt;

&lt;p&gt;Enable HTTP connection pooling and set timeouts to prevent hung threads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.xml.ws.BindingProvider&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="nc"&gt;BindingProvider&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getRequestContext&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.sun.xml.ws.connect.timeout"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.sun.xml.ws.request.timeout"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Optimization 4: JAXB Tuning
&lt;/h2&gt;

&lt;p&gt;JAXB marshalling can dominate CPU time for complex types. Key strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reuse &lt;code&gt;JAXBContext&lt;/code&gt;&lt;/strong&gt; — it's thread-safe and costly to build. Metro caches this internally, but custom marshalling code should too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid unnecessary schema validation&lt;/strong&gt; in production; validate at the boundary during testing instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer flat, well-designed schemas&lt;/strong&gt; over deeply nested polymorphic hierarchies.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Build once, reuse everywhere&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;JAXBContext&lt;/span&gt; &lt;span class="no"&gt;CONTEXT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nc"&gt;JAXBContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Quote&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Optimization 5: Secure Without Sacrificing Speed
&lt;/h2&gt;

&lt;p&gt;WS-Security is inherently&lt;/p&gt;

</description>
      <category>soap</category>
      <category>metro</category>
      <category>java</category>
      <category>webservices</category>
    </item>
    <item>
      <title>Enterprise JavaBeans (EJB): Still Relevant in 2024? (2026-08-25 14:42)</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Tue, 25 Aug 2026 14:42:41 +0000</pubDate>
      <link>https://dev.to/said_olano/enterprise-javabeans-ejb-still-relevant-in-2024-2026-08-25-1442-2a9n</link>
      <guid>https://dev.to/said_olano/enterprise-javabeans-ejb-still-relevant-in-2024-2026-08-25-1442-2a9n</guid>
      <description>&lt;h1&gt;
  
  
  Enterprise JavaBeans (EJB): Still Relevant in 2024?
&lt;/h1&gt;

&lt;p&gt;Enterprise JavaBeans (EJB) has been a cornerstone of enterprise Java development for over two decades. But with the rise of Spring Boot, microservices, and cloud-native architectures, many developers wonder: does EJB still have a place in the modern stack? Let's take an honest, technical look.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Brief History
&lt;/h2&gt;

&lt;p&gt;EJB debuted in 1998 as part of J2EE, promising a standardized component model for distributed, transactional, secure enterprise applications. Early versions (EJB 1.x and 2.x) were notoriously heavyweight, requiring verbose XML descriptors, home/remote interfaces, and cumbersome deployment.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;EJB 3.0&lt;/strong&gt; release (2006) was a turning point. It embraced annotations, convention over configuration, and dependency injection—dramatically reducing boilerplate. Today, EJB lives on within &lt;strong&gt;Jakarta EE&lt;/strong&gt; (formerly Java EE), now stewarded by the Eclipse Foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What EJB Still Does Well
&lt;/h2&gt;

&lt;p&gt;Despite its reputation, EJB provides several genuinely valuable features out of the box.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Declarative Transaction Management
&lt;/h3&gt;

&lt;p&gt;Container-managed transactions remain one of EJB's strongest selling points. You annotate a method and let the container handle transaction boundaries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Stateless&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@PersistenceContext&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;EntityManager&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@TransactionAttribute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TransactionAttributeType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;REQUIRED&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;placeOrder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// If an exception is thrown, the container rolls back automatically&lt;/span&gt;
        &lt;span class="n"&gt;updateInventory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Pooling and Concurrency
&lt;/h3&gt;

&lt;p&gt;Stateless session beans are pooled and managed by the container, giving you thread-safe, scalable components without manual lifecycle handling.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Built-in Security and Asynchronous Processing
&lt;/h3&gt;

&lt;p&gt;Role-based method security and asynchronous invocation are available with simple annotations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Stateless&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReportService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@RolesAllowed&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MANAGER"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Asynchronous&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Report&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;generateReport&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Report&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;buildExpensiveReport&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AsyncResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Case Against EJB
&lt;/h2&gt;

&lt;p&gt;To be fair, the criticisms are real.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ecosystem momentum&lt;/strong&gt;: Spring dominates job postings, tutorials, and community support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heavyweight application servers&lt;/strong&gt;: Traditional EJB deployment on servers like WildFly or WebLogic feels dated next to embedded runtimes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microservices mismatch&lt;/strong&gt;: EJB's roots are in monolithic, server-centric deployments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cognitive overhead&lt;/strong&gt;: Many developers simply never learned it, raising onboarding costs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Modern Comeback: Jakarta EE and MicroProfile
&lt;/h2&gt;

&lt;p&gt;Here's where the story gets interesting. Jakarta EE and &lt;strong&gt;MicroProfile&lt;/strong&gt; have reinvented enterprise Java for the cloud era. Lightweight runtimes such as &lt;strong&gt;Quarkus&lt;/strong&gt;, &lt;strong&gt;Open Liberty&lt;/strong&gt;, and &lt;strong&gt;Payara Micro&lt;/strong&gt; offer fast startup and low memory footprints—directly addressing the "bloat" complaint.&lt;/p&gt;

&lt;p&gt;CDI (Contexts and Dependency Injection) has also absorbed much of what EJB once uniquely offered. In many new projects, developers reach for CDI beans with &lt;code&gt;@Transactional&lt;/code&gt; rather than full EJBs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ApplicationScoped&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InvoiceService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Inject&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;InvoiceRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Transactional&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Invoice&lt;/span&gt; &lt;span class="n"&gt;invoice&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invoice&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This achieves EJB-like transactional behavior with a lighter, more flexible model.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, Is EJB Still Relevant?
&lt;/h2&gt;

&lt;p&gt;The honest answer is &lt;strong&gt;nuanced&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Maintaining legacy Jakarta EE apps&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; — EJB knowledge is essential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greenfield microservices&lt;/td&gt;
&lt;td&gt;Prefer CDI + MicroProfile or Spring Boot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Teams standardized on Jakarta EE servers&lt;/td&gt;
&lt;td&gt;EJB remains a reasonable, supported choice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud-native, container-first workloads&lt;/td&gt;
&lt;td&gt;Lightweight alternatives usually win&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;EJB is not dead—but its role has shifted. As a distinct, must-use technology, it has been largely superseded by CDI and modern Jakarta EE features. However, the &lt;em&gt;concepts&lt;/em&gt; EJB pioneered—declarative transactions, managed lifecycles, and container-provided cross-cutting concerns—are more relevant than ever, just delivered through leaner abstractions.&lt;/p&gt;

&lt;p&gt;If you're maintaining enterprise Java systems, EJB literacy remains a valuable skill in 2024. If you're building something new, understand what EJB does, then choose the lightest tool that meets your needs. Relevance, it turns out, is less about the technology itself and more about the problem you're solving.&lt;/p&gt;

</description>
      <category>java</category>
      <category>ejb</category>
      <category>jakartaee</category>
      <category>enterprisearchitectu</category>
    </item>
    <item>
      <title>AI-Assisted Coding Tools: How to Boost Developer Productivity by 40% While Reducing Defects</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Mon, 24 Aug 2026 22:20:18 +0000</pubDate>
      <link>https://dev.to/said_olano/ai-assisted-coding-tools-how-to-boost-developer-productivity-by-40-while-reducing-defects-433d</link>
      <guid>https://dev.to/said_olano/ai-assisted-coding-tools-how-to-boost-developer-productivity-by-40-while-reducing-defects-433d</guid>
      <description>&lt;p&gt;Organizations are drowning in manual code reviews, repetitive testing, and time spent on defect triage. But what if your development pipeline could get smarter every day?&lt;/p&gt;

&lt;p&gt;I just published a comprehensive guide on operationalizing AI-assisted coding tools and intelligent QA automation in your engineering workflow. This isn't theoretical—it's practical, battle-tested strategies for engineering leaders, CTOs, and DevOps teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here's what's inside:
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;Why AI coding assistants increase productivity by 40% (with real metrics)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documented performance gains from real-world implementations&lt;/li&gt;
&lt;li&gt;ROI calculations based on industry benchmarks&lt;/li&gt;
&lt;li&gt;Cost-benefit analysis for your organization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;How to implement intelligent test automation without replacing human judgment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Best practices for AI-augmented QA processes&lt;/li&gt;
&lt;li&gt;Maintaining code quality while reducing testing time&lt;/li&gt;
&lt;li&gt;Balancing automation with manual testing expertise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;CI/CD pipeline optimization with AI quality gates&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intelligent pipeline gates that catch issues early&lt;/li&gt;
&lt;li&gt;Automated code quality checks at each stage&lt;/li&gt;
&lt;li&gt;Real-time feedback loops for developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Code review automation that actually catches bugs before production&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI-powered static analysis tools&lt;/li&gt;
&lt;li&gt;Pattern recognition for common vulnerabilities&lt;/li&gt;
&lt;li&gt;Integration with existing review workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Defect prediction models that prevent issues before they start&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Machine learning models for bug prediction&lt;/li&gt;
&lt;li&gt;Proactive issue identification&lt;/li&gt;
&lt;li&gt;Historical data analysis for pattern recognition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Team adoption playbook: getting engineers excited (not scared) of AI tools&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change management strategies&lt;/li&gt;
&lt;li&gt;Training programs for development teams&lt;/li&gt;
&lt;li&gt;Overcoming resistance and building trust&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;ROI calculation framework: proving the business case to your leadership&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Metrics that matter to stakeholders&lt;/li&gt;
&lt;li&gt;Cost tracking and savings calculation&lt;/li&gt;
&lt;li&gt;Presentation templates for executives&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Production-Ready Implementation
&lt;/h2&gt;

&lt;p&gt;The guide includes production-ready Java examples featuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spring Boot Integration&lt;/strong&gt;: Complete examples showing how to integrate AI tools into your Spring Boot applications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jenkins Pipeline Automation&lt;/strong&gt;: CI/CD pipeline configurations with AI-powered gates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JUnit/TestNG with AI-powered test generation&lt;/strong&gt;: Automated test creation and optimization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complete metrics collection&lt;/strong&gt;: Track and measure your productivity gains
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example: AI-Assisted Test Generation with JUnit&lt;/span&gt;
&lt;span class="nd"&gt;@Testpublic&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testAIAssistedCodeReview&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// AI automatically generates relevant test cases&lt;/span&gt;
    &lt;span class="nc"&gt;CodeAnalyzer&lt;/span&gt; &lt;span class="n"&gt;analyzer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AICodeAnalyzer&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;ReviewResult&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;analyzer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;analyzeCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sourceCode&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCriticalIssues&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getQualityScore&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Whether you're starting from scratch or already experimenting with AI tools, this guide provides the roadmap to unlock 40%+ productivity gains while reducing defects across your engineering organization:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Assess your current state&lt;/strong&gt; - Evaluate existing development processes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select appropriate tools&lt;/strong&gt; - Choose AI solutions that fit your tech stack&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement incrementally&lt;/strong&gt; - Start with pilot projects before organization-wide rollout&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure and optimize&lt;/strong&gt; - Track metrics and continuously improve&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Key Metrics to Track
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Code review time reduction&lt;/li&gt;
&lt;li&gt;Bug detection rate improvement&lt;/li&gt;
&lt;li&gt;Test coverage increase&lt;/li&gt;
&lt;li&gt;Developer productivity gains&lt;/li&gt;
&lt;li&gt;Time to market acceleration&lt;/li&gt;
&lt;li&gt;Quality improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Time to move beyond "pilot mode" and operationalize AI across your development stack. The tools exist, the ROI is proven, and your engineering teams are ready. Start today and transform how your organization builds software.&lt;/p&gt;




&lt;p&gt;Have you implemented AI-assisted coding tools in your organization? Share your experiences and lessons learned in the comments below!&lt;/p&gt;

</description>
      <category>aidevops</category>
      <category>testingjava</category>
    </item>
    <item>
      <title>AWS CloudFront: Content Delivery Network Optimization (2026-08-24 22:14)</title>
      <dc:creator>Said Olano</dc:creator>
      <pubDate>Mon, 24 Aug 2026 22:14:08 +0000</pubDate>
      <link>https://dev.to/said_olano/aws-cloudfront-content-delivery-network-optimization-2026-08-24-2214-10og</link>
      <guid>https://dev.to/said_olano/aws-cloudfront-content-delivery-network-optimization-2026-08-24-2214-10og</guid>
      <description>&lt;h1&gt;
  
  
  AWS CloudFront: Content Delivery Network Optimization
&lt;/h1&gt;

&lt;p&gt;Amazon CloudFront is AWS's globally distributed content delivery network (CDN) that caches content at edge locations close to your users. While spinning up a basic distribution is straightforward, extracting maximum performance and cost efficiency requires deliberate optimization. This post covers practical techniques to get the most out of CloudFront.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why CloudFront Optimization Matters
&lt;/h2&gt;

&lt;p&gt;An unoptimized CDN can result in low cache hit ratios, high origin load, inflated data transfer costs, and slower response times for end users. The goal of optimization is simple: serve more requests from the edge, reduce origin round-trips, and control costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Maximize Your Cache Hit Ratio
&lt;/h2&gt;

&lt;p&gt;The single most impactful metric is your &lt;strong&gt;cache hit ratio&lt;/strong&gt;—the percentage of requests served from the edge instead of the origin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Normalize Cache Keys
&lt;/h3&gt;

&lt;p&gt;By default, every unique combination of query strings, headers, and cookies can create a separate cache entry. Fragmenting your cache reduces hit ratios. Use &lt;strong&gt;Cache Policies&lt;/strong&gt; to include only the values that actually affect the response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"CachePolicyConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OptimizedPolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"DefaultTTL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;86400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"MaxTTL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31536000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"MinTTL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ParametersInCacheKeyAndForwardedToOrigin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"QueryStringsConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"QueryStringBehavior"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"whitelist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"QueryStrings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"HeadersConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"HeaderBehavior"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"none"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"CookiesConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"CookieBehavior"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"none"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Set Appropriate TTLs
&lt;/h3&gt;

&lt;p&gt;Control caching duration through origin &lt;code&gt;Cache-Control&lt;/code&gt; headers, or override them with CloudFront TTL settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Cache-Control: public, max-age=86400, s-maxage=604800
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;s-maxage&lt;/code&gt; to instruct CloudFront (a shared cache) to cache longer than browsers.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Enable Compression
&lt;/h2&gt;

&lt;p&gt;CloudFront can automatically compress objects using Gzip and Brotli, dramatically reducing transfer size for text-based assets (HTML, CSS, JS, JSON).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;Compress: true&lt;/code&gt; in your cache behavior.&lt;/li&gt;
&lt;li&gt;Ensure the viewer sends &lt;code&gt;Accept-Encoding: gzip, br&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Only objects between 1,000 and 10,000,000 bytes are compressed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Brotli typically achieves 15–25% better compression than Gzip for text content.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Use Origin Shield
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Origin Shield&lt;/strong&gt; adds an additional caching layer between edge locations and your origin. All edge caches funnel misses through a single regional cache, which collapses duplicate requests and further protects your origin.&lt;/p&gt;

&lt;p&gt;Enable it in the region closest to your origin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Origin Shield Region: us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially valuable for origins with limited capacity or high request volumes.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Optimize with Cache and Origin Request Policies
&lt;/h2&gt;

&lt;p&gt;Separate what's used for the &lt;strong&gt;cache key&lt;/strong&gt; from what's &lt;strong&gt;forwarded to the origin&lt;/strong&gt;. You might not want to vary the cache by an &lt;code&gt;Authorization&lt;/code&gt; header but still need to forward it to the origin. Use an &lt;strong&gt;Origin Request Policy&lt;/strong&gt; for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudfront create-origin-request-policy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--origin-request-policy-config&lt;/span&gt; file://origin-request-policy.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Leverage Edge Functions
&lt;/h2&gt;

&lt;p&gt;Move logic to the edge to reduce origin load and latency:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Runtime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CloudFront Functions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Header manipulation, redirects, URL rewrites&lt;/td&gt;
&lt;td&gt;Lightweight JS (sub-ms)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lambda@Edge&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Complex logic, auth, origin selection&lt;/td&gt;
&lt;td&gt;Node.js/Python&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Example CloudFront Function to add security headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;strict-transport-security&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;max-age=63072000; includeSubDomains; preload&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Control Costs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Choose the right price class.&lt;/strong&gt; If your audience is regional, use &lt;code&gt;PriceClass_100&lt;/code&gt; (North America and Europe only) to avoid paying for expensive edge locations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor data transfer.&lt;/strong&gt; Origin-to-edge transfer over CloudFront is often cheaper than direct S3 or EC2 egress.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Savings Bundles&lt;/strong&gt; if you have predictable, high-volume traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Monitor and Iterate
&lt;/h2&gt;

&lt;p&gt;Enable &lt;strong&gt;real-time logs&lt;/strong&gt; and CloudWatch metrics to track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CacheHitRate&lt;/code&gt; — aim for 85%+ on static content&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;OriginLatency&lt;/code&gt; — spikes indicate origin bottlenecks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;4xxErrorRate&lt;/code&gt; / &lt;code&gt;5xxErrorRate&lt;/code&gt; — configuration or origin issues
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudwatch get-metric-statistics &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; AWS/CloudFront &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metric-name&lt;/span&gt; CacheHitRate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dimensions&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;DistributionId,Value&lt;span class="o"&gt;=&lt;/span&gt;EXXXXXX &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--statistics&lt;/span&gt; Average &lt;span class="nt"&gt;--period&lt;/span&gt; 3600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;CloudFront optimization is an iterative process. Start by normalizing cache keys and setting sensible TTLs to boost your hit ratio, enable compression and Origin Shield to reduce origin load, and push logic to the edge with functions. Continuously monitor your metrics and refine your policies. These changes compound into faster user experiences and meaningful cost savings.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudfront</category>
      <category>cdn</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
