<?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: Code Green</title>
    <description>The latest articles on DEV Community by Code Green (@codegreen).</description>
    <link>https://dev.to/codegreen</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F582887%2F46d6cd27-247f-4af7-ab18-e585483accbe.jpeg</url>
      <title>DEV Community: Code Green</title>
      <link>https://dev.to/codegreen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codegreen"/>
    <language>en</language>
    <item>
      <title>What is out of memory exception in java</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Tue, 16 Dec 2025 14:15:01 +0000</pubDate>
      <link>https://dev.to/codegreen/what-is-out-of-memory-exception-in-java-4j1d</link>
      <guid>https://dev.to/codegreen/what-is-out-of-memory-exception-in-java-4j1d</guid>
      <description>&lt;h2&gt;
  
  
  OutOfMemoryError in Java
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;OutOfMemoryError (OOME)&lt;/strong&gt; is a runtime error thrown when the Java Virtual Machine cannot allocate an object because it is out of memory and no more memory could be made available by the garbage collector.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common causes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Heap exhaustion:&lt;/strong&gt; too many objects or very large objects exceed the JVM heap (-Xmx).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PermGen/Metaspace exhaustion:&lt;/strong&gt; too many or too-large class metadata (PermGen in older JVMs, Metaspace in newer) due to excessive dynamic class loading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native memory shortage:&lt;/strong&gt; insufficient native memory for JNI, direct ByteBuffers, thread stacks, or JVM internals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory leak:&lt;/strong&gt; long-lived references (static collections, caches) prevent garbage collection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Excessive thread creation:&lt;/strong&gt; each thread consumes stack/native memory; many threads can exhaust memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large temporary allocations:&lt;/strong&gt; creating huge arrays or concatenating strings can spike memory use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Typical symptoms / error messages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;java.lang.OutOfMemoryError: Java heap space&lt;/li&gt;
&lt;li&gt;java.lang.OutOfMemoryError: Metaspace (or PermGen)&lt;/li&gt;
&lt;li&gt;java.lang.OutOfMemoryError: Direct buffer memory&lt;/li&gt;
&lt;li&gt;java.lang.OutOfMemoryError: GC overhead limit exceeded&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Diagnosis steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check JVM options:&lt;/strong&gt; confirm -Xmx, -Xms, -XX:MaxMetaspaceSize, -Xss settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable GC logging:&lt;/strong&gt; e.g., -Xlog:gc* (JDK9+) or -verbose:gc and -XX:+PrintGCDetails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capture heap dump on OOME:&lt;/strong&gt; -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analyze heap dump:&lt;/strong&gt; use Eclipse MAT, VisualVM, or YourKit to find largest objects and retained paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Profile memory:&lt;/strong&gt; run profiler to identify leaks and allocation hotspots.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inspect thread count / native usage:&lt;/strong&gt; jstack, ps, pmap, lsof for native allocations and thread stacks.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Remediation strategies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fix leaks:&lt;/strong&gt; remove unnecessary strong references, use weak/soft references or caches with eviction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tune JVM memory:&lt;/strong&gt; increase -Xmx, -Xms, or Metaspace if appropriate and host has capacity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduce memory footprint:&lt;/strong&gt; optimize data structures, use primitives, stream/process large data in chunks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limit concurrency:&lt;/strong&gt; reduce thread count or use thread pools to cap parallelism.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use off-heap storage carefully:&lt;/strong&gt; for large buffers prefer pooled direct buffers and monitor Direct buffer memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improve GC:&lt;/strong&gt; choose a GC algorithm suited to workload (G1, ZGC, Shenandoah) and tune GC flags.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid loading many classes dynamically&lt;/strong&gt; or ensure proper classloader cleanup.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
    </item>
    <item>
      <title>Explain Predicate and Consumer in Java</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Tue, 16 Dec 2025 14:12:37 +0000</pubDate>
      <link>https://dev.to/codegreen/explain-predicate-and-consumer-in-java-4k9g</link>
      <guid>https://dev.to/codegreen/explain-predicate-and-consumer-in-java-4k9g</guid>
      <description>&lt;h2&gt;
  
  
  Predicate and Consumer in Java
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Predicate
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What:&lt;/strong&gt; A functional interface in java.util.function representing a boolean-valued function of one argument.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signature:&lt;/strong&gt; &lt;code&gt;boolean test(T t)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Common use:&lt;/strong&gt; filtering, conditional checks (e.g., stream.filter).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default/composed methods:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;default Predicate&amp;lt;T&amp;gt; and(Predicate&amp;lt;? super T&amp;gt; other)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;default Predicate&amp;lt;T&amp;gt; or(Predicate&amp;lt;? super T&amp;gt; other)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;default Predicate&amp;lt;T&amp;gt; negate()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;static &amp;lt;T&amp;gt; Predicate&amp;lt;T&amp;gt; isEqual(Object targetRef)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Example:&lt;/strong&gt;
&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;Predicate&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;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;isEmpty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Predicate&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;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;startsWithA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Predicate&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;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;combined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;negate&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;and&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startsWithA&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;combined&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Apple"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consumer&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What:&lt;/strong&gt; A functional interface in java.util.function representing an operation that accepts a single input and returns no result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signature:&lt;/strong&gt; void accept(T t)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Common use:&lt;/strong&gt; performing actions (e.g., stream.forEach, side-effects, logging).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default/composed method:&lt;/strong&gt; default Consumer andThen(Consumer&amp;lt;? super T&amp;gt; after)
&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;Consumer&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;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Consumer&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;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;exclaim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Consumer&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;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;combined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andThen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exclaim&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;combined&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints "Hello" then "Hello!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&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;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Anna"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Predicate&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;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;startsWithA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Consumer&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;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;printer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;names&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;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startsWithA&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
     &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;printer&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints "Alice" and "Anna"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
    </item>
    <item>
      <title>What is executor service in java</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Tue, 16 Dec 2025 14:09:01 +0000</pubDate>
      <link>https://dev.to/codegreen/what-is-executor-service-in-java-2pka</link>
      <guid>https://dev.to/codegreen/what-is-executor-service-in-java-2pka</guid>
      <description>&lt;h2&gt;
  
  
  ExecutorService in Java
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ExecutorService&lt;/strong&gt; is a high-level interface in java.util.concurrent that represents an asynchronous execution service which accepts tasks (Runnable or Callable) and manages a pool of threads to run them. It decouples task submission from task execution and provides lifecycle control and result/future handling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key responsibilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Accept tasks via submit/execute.&lt;/li&gt;
&lt;li&gt;Manage worker threads (thread pooling).&lt;/li&gt;
&lt;li&gt;Return Future objects for monitoring results/cancellation.&lt;/li&gt;
&lt;li&gt;Support orderly shutdown and termination waiting.&lt;/li&gt;
&lt;li&gt;Optionally schedule tasks when using ScheduledExecutorService (sub-interface).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Important methods
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;execute(Runnable task) — submit a task without a result.&lt;/li&gt;
&lt;li&gt; Future submit(Callable task) — submit a task that returns a result.&lt;/li&gt;
&lt;li&gt;Future&amp;lt;?&amp;gt; submit(Runnable task) — submit Runnable and get Future for cancellation.&lt;/li&gt;
&lt;li&gt; List&amp;gt; invokeAll(Collection&amp;lt;? extends Callable&amp;gt; tasks) — run tasks and wait for all.&lt;/li&gt;
&lt;li&gt; T invokeAny(Collection&amp;lt;? extends Callable&amp;gt; tasks) — run tasks and return one successful result.&lt;/li&gt;
&lt;li&gt;shutdown() — start orderly shutdown (no new tasks).&lt;/li&gt;
&lt;li&gt;List shutdownNow() — attempt to stop executing tasks and return pending tasks.&lt;/li&gt;
&lt;li&gt;boolean isShutdown(), boolean isTerminated(), awaitTermination(long timeout, TimeUnit unit).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Common implementations / providers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Executors.newFixedThreadPool(n) — fixed-size pool (returns ExecutorService).&lt;/li&gt;
&lt;li&gt;Executors.newCachedThreadPool() — dynamically-sized pool.&lt;/li&gt;
&lt;li&gt;Executors.newSingleThreadExecutor() — single-threaded executor.&lt;/li&gt;
&lt;li&gt;ThreadPoolExecutor — configurable concrete implementation.&lt;/li&gt;
&lt;li&gt;ScheduledThreadPoolExecutor — implements ScheduledExecutorService for delayed/periodic tasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ExecutorService&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newFixedThreadPool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;);&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;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// do work&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="o"&gt;;&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// blocks until done&lt;/span&gt;
&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdown&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Best practices&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prefer ExecutorService over manually creating Threads.&lt;/li&gt;
&lt;li&gt;Always call &lt;code&gt;shutdown()&lt;/code&gt; (or &lt;code&gt;shutdownNow()&lt;/code&gt;) to allow JVM exit.&lt;/li&gt;
&lt;li&gt;Use bounded queues and appropriate pool sizes to avoid resource exhaustion.&lt;/li&gt;
&lt;li&gt;Use Future or CompletableFuture for result composition and cancellation handling.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>java</category>
    </item>
    <item>
      <title>explain thread pool in java</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Tue, 16 Dec 2025 14:06:24 +0000</pubDate>
      <link>https://dev.to/codegreen/explain-thread-pool-in-java-21j2</link>
      <guid>https://dev.to/codegreen/explain-thread-pool-in-java-21j2</guid>
      <description>&lt;h2&gt;
  
  
  Thread Pool in Java
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;thread pool&lt;/strong&gt; is a collection of pre-created worker threads that execute submitted tasks, reusing threads to avoid the overhead of creating and destroying threads for each task. Java provides built-in thread-pool support in the java.util.concurrent package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key benefits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced latency:&lt;/strong&gt; avoid thread creation cost for each task.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controlled concurrency:&lt;/strong&gt; limit number of concurrent threads to match resources.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource management:&lt;/strong&gt; prevents thread explosion that can exhaust memory/CPU.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task queuing:&lt;/strong&gt; tasks wait in a queue when all threads are busy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Core concepts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Worker threads:&lt;/strong&gt; threads that repeatedly take tasks from a queue and run them.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task (Runnable/Callable):&lt;/strong&gt; units of work submitted to the pool.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task queue:&lt;/strong&gt; holds waiting tasks (bounded or unbounded).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pool size:&lt;/strong&gt; number of active worker threads (core and maximum).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep-alive time:&lt;/strong&gt; time non-core threads may remain idle before terminating.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RejectedExecutionHandler:&lt;/strong&gt; policy for handling tasks when the queue is full and pool is at max.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Java APIs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Executors factory methods (java.util.concurrent.Executors):

&lt;ul&gt;
&lt;li&gt;Executors.newFixedThreadPool(n): fixed-size pool.&lt;/li&gt;
&lt;li&gt;Executors.newCachedThreadPool(): dynamic pool that creates threads as needed and reuses idle ones.&lt;/li&gt;
&lt;li&gt;Executors.newSingleThreadExecutor(): single-worker pool.&lt;/li&gt;
&lt;li&gt;Executors.newScheduledThreadPool(n): for delayed/periodic tasks.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Core classes/interfaces:

&lt;ul&gt;
&lt;li&gt;Executor: single-method execute(Runnable).&lt;/li&gt;
&lt;li&gt;ExecutorService: extends Executor; supports lifecycle (submit, shutdown, awaitTermination).&lt;/li&gt;
&lt;li&gt;ScheduledExecutorService: supports scheduling tasks.&lt;/li&gt;
&lt;li&gt;ThreadPoolExecutor: configurable concrete implementation.&lt;/li&gt;
&lt;li&gt;Future / FutureTask: represent task results and allow cancellation.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Typical ThreadPoolExecutor constructor parameters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;corePoolSize — minimum number of threads to keep.&lt;/li&gt;
&lt;li&gt;maximumPoolSize — maximum allowed threads.&lt;/li&gt;
&lt;li&gt;keepAliveTime &amp;amp; unit — idle time before reclaiming extra threads.&lt;/li&gt;
&lt;li&gt;workQueue — queue implementation (e.g., LinkedBlockingQueue, ArrayBlockingQueue, SynchronousQueue).&lt;/li&gt;
&lt;li&gt;threadFactory — creates new threads.&lt;/li&gt;
&lt;li&gt;handler — RejectedExecutionHandler when saturated (AbortPolicy, CallerRunsPolicy, DiscardPolicy, DiscardOldestPolicy).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example: fixed thread pool
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ExecutorService&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newFixedThreadPool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for&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;i&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task "&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="s"&gt;" running in "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;ignored&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;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdown&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Best practices
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Prefer Executors factory methods for common use-cases; use ThreadPoolExecutor for fine control.&lt;/li&gt;
&lt;li&gt;Choose queue type based on desired behavior: bounded queue for backpressure, SynchronousQueue for direct handoff.&lt;/li&gt;
&lt;li&gt;Set sensible pool sizes: typically related to number of CPU cores (IO-bound vs CPU-bound tasks differ).&lt;/li&gt;
&lt;li&gt;Always shut down ExecutorService (shutdown or shutdownNow) to allow JVM exit.&lt;/li&gt;
&lt;li&gt;Use Future to get results or cancel tasks; prefer CompletableFuture for composition.&lt;/li&gt;
&lt;li&gt;Avoid unbounded queues with unbounded task submission — can lead to OOM.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>java</category>
    </item>
    <item>
      <title>What is exchange class in java</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Tue, 16 Dec 2025 14:03:01 +0000</pubDate>
      <link>https://dev.to/codegreen/what-is-exchange-class-in-java-olm</link>
      <guid>https://dev.to/codegreen/what-is-exchange-class-in-java-olm</guid>
      <description>&lt;h2&gt;
  
  
  Exchange class in Java
&lt;/h2&gt;

&lt;p&gt;An "Exchange" class typically refers to a plain Java class used to encapsulate a message or a data exchange between components (commonly seen in messaging frameworks like Apache Camel). It is not a built-in Java SE class but a design pattern/POJO used to carry payload, metadata, and processing state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common responsibilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Payload:&lt;/strong&gt; holds the main message/data (object or byte[]).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers/Properties:&lt;/strong&gt; stores metadata (key-value pairs).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exchange ID:&lt;/strong&gt; unique identifier for the exchange instance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pattern/Type:&lt;/strong&gt; indicates message exchange pattern (e.g., InOnly, InOut).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attachments:&lt;/strong&gt; optional binary or additional parts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exception/Status:&lt;/strong&gt; holds processing exceptions or status flags.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing/Endpoint info:&lt;/strong&gt; source/destination identifiers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Typical structure (example)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Exchange&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&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="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&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;headers&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;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Exchange&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="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&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;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;;&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;getId&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="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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;getBody&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="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;;&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;setBody&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;;&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;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="nf"&gt;getHeaders&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="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;;&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;setHeader&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;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;headers&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="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;);&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;Object&lt;/span&gt; &lt;span class="nf"&gt;getHeader&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;name&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="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&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;Exception&lt;/span&gt; &lt;span class="nf"&gt;getException&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="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;;&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;setException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exception&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;



</description>
      <category>java</category>
    </item>
    <item>
      <title>NoSQL vs. SQL Databases</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Thu, 04 Dec 2025 12:26:33 +0000</pubDate>
      <link>https://dev.to/codegreen/nosql-vs-sql-databases-10kl</link>
      <guid>https://dev.to/codegreen/nosql-vs-sql-databases-10kl</guid>
      <description>&lt;h2&gt;
  
  
  DynamoDB vs. Traditional SQL Databases
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Characteristic&lt;/th&gt;
&lt;th&gt;DynamoDB (NoSQL)&lt;/th&gt;
&lt;th&gt;Relational SQL DB (e.g., PostgreSQL, MySQL)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Key‑value + document; items are schemaless.&lt;/td&gt;
&lt;td&gt;Fixed schema with tables, rows, columns, data types.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Query language&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Primary‑key lookups, secondary indexes; limited ad‑hoc queries.&lt;/td&gt;
&lt;td&gt;Full‑featured SQL (joins, aggregates, sub‑queries).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Horizontal scaling automatically; virtually unlimited throughput.&lt;/td&gt;
&lt;td&gt;Typically vertical scaling; sharding/partitioning is manual.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consistency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Configurable (eventual or strong per‑item).&lt;/td&gt;
&lt;td&gt;Strong ACID consistency by default.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transactions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Up to 25 items per transaction (ACID).&lt;/td&gt;
&lt;td&gt;Multi‑row, multi‑table ACID transactions are native.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Joins&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not supported; denormalize or use secondary indexes.&lt;/td&gt;
&lt;td&gt;Native joins across tables.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Predictable O(1) reads/writes when accessed by PK/SK.&lt;/td&gt;
&lt;td&gt;Performance depends on indexes, query plans, and data size.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pay‑per‑request (on‑demand) or provisioned capacity; no licensing.&lt;/td&gt;
&lt;td&gt;Usually per‑instance (CPU, RAM, storage) plus licensing.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Primary Key (PK) and Sort Key (SK) in DynamoDB
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Partition Key (PK)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hashes the key value to determine the physical partition that stores the item. All items with the same PK reside on the same partition and are &lt;strong&gt;co‑located&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Sort Key (SK)&lt;/strong&gt; (optional)&lt;/td&gt;
&lt;td&gt;Within a partition, items are ordered by the SK value. Enables range queries (&lt;code&gt;BETWEEN&lt;/code&gt;, &lt;code&gt;begins_with&lt;/code&gt;) on items that share the same PK.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Composite Primary Key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Combination of PK + SK uniquely identifies an item. The PK alone can also be a primary key (no SK).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Why PK/SK Matter
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fast lookups&lt;/strong&gt;: &lt;code&gt;GetItem&lt;/code&gt; or &lt;code&gt;Query&lt;/code&gt; on PK (and optional SK) is O(1) because DynamoDB knows exactly which partition to read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data modeling&lt;/strong&gt;: By choosing PK/SK wisely you can represent one‑to‑many or many‑to‑many relationships in a single table (single‑table design).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access patterns&lt;/strong&gt;: All queries that share the same PK are served from the same partition, giving low latency and high throughput for that access pattern.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Comparison with a Traditional SQL Primary Key
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;DynamoDB PK/SK&lt;/th&gt;
&lt;th&gt;SQL Primary Key&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Uniqueness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PK alone must be unique; PK + SK together must be unique.&lt;/td&gt;
&lt;td&gt;Single column or composite column(s) must be unique across the whole table.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Physical placement&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PK determines the physical partition; SK only orders items within that partition.&lt;/td&gt;
&lt;td&gt;No concept of physical partitioning at the key level (unless using sharding).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Range queries&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SK enables efficient range queries &lt;strong&gt;only&lt;/strong&gt; within the same PK.&lt;/td&gt;
&lt;td&gt;SQL primary key (or any indexed column) can be used for range queries across the whole table.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Joins&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not supported; relationships are expressed by embedding related data or using PK/SK patterns.&lt;/td&gt;
&lt;td&gt;Primary keys are used to join tables (&lt;code&gt;JOIN … ON pk = fk&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Schema flexibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Items with the same PK can have different attributes; SK does not enforce a schema.&lt;/td&gt;
&lt;td&gt;All rows must conform to the table’s column definitions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability impact&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Adding more items with the same PK can create a hot partition; you may need to shard the PK.&lt;/td&gt;
&lt;td&gt;Adding rows does not affect partitioning unless you manually shard; indexes handle scaling.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Bottom line:&lt;/strong&gt; DynamoDB’s PK/SK model is a &lt;strong&gt;distribution and ordering mechanism&lt;/strong&gt; optimized for massive scale and predictable latency, whereas a SQL primary key is primarily a &lt;strong&gt;uniqueness constraint&lt;/strong&gt; used for relational integrity and joins. The choice of PK and SK drives your access patterns and performance in DynamoDB, while in SQL you design primary keys to support relational queries and referential integrity.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>dynamodb</category>
    </item>
    <item>
      <title>AWS - Secure, High‑Throughput Ingestion Pipeline for Large Binary Objects</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Thu, 04 Dec 2025 09:47:03 +0000</pubDate>
      <link>https://dev.to/codegreen/aws-secure-high-throughput-ingestion-pipeline-for-large-binary-objects-4hic</link>
      <guid>https://dev.to/codegreen/aws-secure-high-throughput-ingestion-pipeline-for-large-binary-objects-4hic</guid>
      <description>&lt;p&gt;Your application must accept user‑uploaded video files (average size ≈ 150 MB, peak size ≈ 1 GB) and store them in Amazon S3.&lt;br&gt;&lt;br&gt;
Requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Direct client upload&lt;/strong&gt; (no server‑side proxy) with minimal latency.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server‑side validation&lt;/strong&gt; of file type and size before the object becomes publicly accessible.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic virus scanning&lt;/strong&gt; after upload.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retention policy&lt;/strong&gt;: keep objects for 90 days, then archive to Glacier Deep Archive.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access control&lt;/strong&gt;: only authenticated users can read their own files; no public read access.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Design the S3 architecture and supporting AWS services to satisfy these constraints. Include the steps a client follows, the AWS resources you would configure (cost, latency, complexity).&lt;/p&gt;

&lt;h3&gt;
  
  
  1. High‑Level Flow (client‑side)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Client requests a pre‑signed PUT URL&lt;/strong&gt; from your backend API (e.g., &lt;code&gt;/upload-url?filename=video.mp4&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;Backend &lt;strong&gt;generates a pre‑signed URL&lt;/strong&gt; using &lt;code&gt;s3:PutObject&lt;/code&gt; permission, limited to the specific bucket, key prefix (e.g., &lt;code&gt;uploads/{userId}/{uuid}.mp4&lt;/code&gt;), and a short expiration (5 min).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client uploads the file directly to S3&lt;/strong&gt; via HTTP PUT using the URL.
&lt;/li&gt;
&lt;li&gt;S3 triggers an &lt;strong&gt;ObjectCreated&lt;/strong&gt; event → Lambda &lt;strong&gt;validation &amp;amp; scanning&lt;/strong&gt; workflow.
&lt;/li&gt;
&lt;li&gt;If validation passes, Lambda &lt;strong&gt;moves the object&lt;/strong&gt; to the final location (&lt;code&gt;private/{userId}/{uuid}.mp4&lt;/code&gt;) and updates a DynamoDB record that tracks ownership and status.
&lt;/li&gt;
&lt;li&gt;If validation fails, Lambda &lt;strong&gt;deletes the object&lt;/strong&gt; and optionally notifies the user.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Required AWS Resources
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Key Configuration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;S3 Bucket&lt;/strong&gt; (&lt;code&gt;my‑media‑bucket&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Store raw uploads and final objects&lt;/td&gt;
&lt;td&gt;- Block public access (Bucket Policy).&lt;br&gt;- Enable &lt;strong&gt;Object Lock&lt;/strong&gt; (optional) for tamper‑evidence.&lt;br&gt;- Enable &lt;strong&gt;Versioning&lt;/strong&gt; (helps with accidental deletes).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IAM Role for Backend API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generate pre‑signed URLs&lt;/td&gt;
&lt;td&gt;Policy: &lt;code&gt;s3:PutObject&lt;/code&gt; on &lt;code&gt;uploads/${userId}/*&lt;/code&gt; with condition &lt;code&gt;s3:x-amz-content-sha256&lt;/code&gt; optional.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Lambda Function&lt;/strong&gt; (&lt;code&gt;ValidateAndScan&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Validate MIME type, size, run antivirus, move object&lt;/td&gt;
&lt;td&gt;- Triggered by &lt;strong&gt;S3 ObjectCreated&lt;/strong&gt; on &lt;code&gt;uploads/&lt;/code&gt; prefix.&lt;br&gt;- Permissions: &lt;code&gt;s3:GetObject&lt;/code&gt;, &lt;code&gt;s3:PutObject&lt;/code&gt;, &lt;code&gt;s3:DeleteObject&lt;/code&gt;, &lt;code&gt;dynamodb:PutItem&lt;/code&gt;.&lt;br&gt;- Timeout: up to 15 min (max for scanning large files).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Amazon GuardDuty / Amazon Macie&lt;/strong&gt; (optional)&lt;/td&gt;
&lt;td&gt;Continuous threat detection on bucket&lt;/td&gt;
&lt;td&gt;Can be enabled at bucket level; not required for per‑file scan.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Amazon Inspector / ClamAV&lt;/strong&gt; (via Lambda)&lt;/td&gt;
&lt;td&gt;Virus scanning&lt;/td&gt;
&lt;td&gt;Deploy ClamAV database in the Lambda layer; update daily via a scheduled Lambda.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;DynamoDB Table&lt;/strong&gt; (&lt;code&gt;UserFiles&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Metadata: owner, status, S3 key, timestamps&lt;/td&gt;
&lt;td&gt;Primary key: &lt;code&gt;fileId&lt;/code&gt; (UUID). Sort key optional for user partitioning.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;S3 Lifecycle Policy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;90‑day transition → Glacier Deep Archive, then expiration&lt;/td&gt;
&lt;td&gt;- Rule 1: &lt;code&gt;Transition&lt;/code&gt; after 90 days to &lt;code&gt;GLACIER_DEEP_ARCHIVE&lt;/code&gt;.&lt;br&gt;- Rule 2: &lt;code&gt;Expiration&lt;/code&gt; after 7 years (or as required).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Gateway / ALB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Expose &lt;code&gt;/upload-url&lt;/code&gt; endpoint (and optional download endpoint)&lt;/td&gt;
&lt;td&gt;Use &lt;strong&gt;IAM authorizer&lt;/strong&gt; or &lt;strong&gt;Cognito&lt;/strong&gt; for user authentication.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CloudWatch Alarms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Monitor failed validations, scan errors&lt;/td&gt;
&lt;td&gt;Metrics: &lt;code&gt;LambdaErrors&lt;/code&gt;, &lt;code&gt;S3ObjectCreated&lt;/code&gt;, &lt;code&gt;ValidationFailures&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Detailed Lambda Validation &amp;amp; Scanning Logic (pseudo‑code)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&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;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s3Event&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S3Event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;s3Event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Records&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;
        &lt;span class="n"&gt;key&lt;/span&gt;    &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;

        &lt;span class="c"&gt;// 1. Get object metadata (size, content‑type)&lt;/span&gt;
        &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HeadObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HeadObjectInput&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;:&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c"&gt;// 2. Size check&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentLength&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;// &amp;gt;1 GB&lt;/span&gt;
            &lt;span class="n"&gt;deleteObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;notifyUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File too large"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c"&gt;// 3. Content‑type whitelist (e.g., video/mp4, video/webm)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;allowedMime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;deleteObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;notifyUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unsupported file type"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c"&gt;// 4. Download to /tmp (max 512 MB per Lambda, so for &amp;gt;512 MB use S3 Select or multipart copy)&lt;/span&gt;
        &lt;span class="c"&gt;// For simplicity assume &amp;lt;512 MB; larger files can be scanned via S3 Object Lambda (advanced).&lt;/span&gt;

        &lt;span class="c"&gt;// 5. Virus scan with ClamAV&lt;/span&gt;
        &lt;span class="n"&gt;infected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;scanWithClamAV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;infected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;deleteObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;notifyUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File failed virus scan"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c"&gt;// 6. Move to final location (copy + delete)&lt;/span&gt;
        &lt;span class="n"&gt;destKey&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"private/%s/%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userIDFromKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;copyObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;destKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;deleteObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;// 7. Record metadata in DynamoDB&lt;/span&gt;
        &lt;span class="n"&gt;putItem&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dynamodb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PutItemInput&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;TableName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UserFiles"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AttributeValue&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s"&gt;"fileId"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AttributeValueMemberS&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewString&lt;/span&gt;&lt;span class="p"&gt;()},&lt;/span&gt;
                &lt;span class="s"&gt;"userId"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AttributeValueMemberS&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;userIDFromKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
                &lt;span class="s"&gt;"s3Key"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AttributeValueMemberS&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;destKey&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="s"&gt;"status"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AttributeValueMemberS&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"READY"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="s"&gt;"uploaded"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AttributeValueMemberS&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RFC3339&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="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dynamoClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PutItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;putItem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&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="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Summary of Steps for a Client
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Authenticate (Cognito, JWT, etc.).&lt;/li&gt;
&lt;li&gt;POST /upload‑url with filename &amp;amp; size → receive pre‑signed PUT URL.&lt;/li&gt;
&lt;li&gt;PUT the file directly to S3 using the URL.&lt;/li&gt;
&lt;li&gt;Poll (or receive a webhook) for upload status (metadata stored in DynamoDB).&lt;/li&gt;
&lt;li&gt;GET the file via a signed download URL generated by the backend (or via API that checks ownership).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This architecture delivers low‑latency, secure uploads, enforces validation and virus scanning, automatically manages retention, and isolates each user’s data while keeping operational costs reasonable.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>s3</category>
    </item>
    <item>
      <title>Designing a Scalable, Cost‑Effective Access Pattern for a High‑Throughput Time‑Series Store</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Thu, 04 Dec 2025 09:39:17 +0000</pubDate>
      <link>https://dev.to/codegreen/designing-a-scalable-cost-effective-access-pattern-for-a-high-throughput-time-series-store-d28</link>
      <guid>https://dev.to/codegreen/designing-a-scalable-cost-effective-access-pattern-for-a-high-throughput-time-series-store-d28</guid>
      <description>&lt;p&gt;You must store IoT sensor readings that arrive at a rate of &lt;strong&gt;10,000 writes per second&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Each reading includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;deviceId&lt;/code&gt; (string, partition key)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;timestamp&lt;/code&gt; (ISO‑8601, sort key)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;temperature&lt;/code&gt;, &lt;code&gt;humidity&lt;/code&gt;, &lt;code&gt;pressure&lt;/code&gt; (numeric)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;metadata&lt;/code&gt; (JSON blob, optional)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fast point‑lookup&lt;/strong&gt; for the latest reading of a given &lt;code&gt;deviceId&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficient range queries&lt;/strong&gt; to retrieve all readings for a device within a time window (e.g., last 24 h).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retention policy&lt;/strong&gt;: keep data for 30 days, then automatically expire.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost‑optimized&lt;/strong&gt; for the high write throughput while keeping read latency &amp;lt; 50 ms.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Table Schema &amp;amp; Primary Key
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;deviceId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Partition key&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timestamp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String (ISO‑8601, e.g., &lt;code&gt;2025-12-04T12:34:56Z&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Sort key&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;temperature&lt;/code&gt;, &lt;code&gt;humidity&lt;/code&gt;, &lt;code&gt;pressure&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Number&lt;/td&gt;
&lt;td&gt;Payload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;metadata&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String (JSON)&lt;/td&gt;
&lt;td&gt;Optional payload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ttl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number (epoch seconds)&lt;/td&gt;
&lt;td&gt;TTL attribute for expiration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why this PK?&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Guarantees all readings for a device are stored together, enabling efficient range queries (&lt;code&gt;deviceId&lt;/code&gt; = X AND &lt;code&gt;timestamp&lt;/code&gt; BETWEEN …).
&lt;/li&gt;
&lt;li&gt;Allows a &lt;strong&gt;single‑item query&lt;/strong&gt; for the latest reading by using &lt;code&gt;ScanIndexForward=false&lt;/code&gt; and &lt;code&gt;Limit=1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Indexing Strategy
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Index&lt;/th&gt;
&lt;th&gt;Partition Key&lt;/th&gt;
&lt;th&gt;Sort Key&lt;/th&gt;
&lt;th&gt;Use‑case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary Table&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;deviceId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;timestamp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Point lookup &amp;amp; range queries per device&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Global Secondary Index (GSI) – &lt;code&gt;DeviceLatestGSI&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;deviceId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;timestamp&lt;/code&gt; (projected as &lt;strong&gt;&lt;code&gt;DESC&lt;/code&gt;&lt;/strong&gt;)&lt;/td&gt;
&lt;td&gt;Direct query for the latest reading without scanning the whole partition (use &lt;code&gt;Limit=1&lt;/code&gt;, &lt;code&gt;ScanIndexForward=false&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Optional GSI – &lt;code&gt;MetricGSI&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;metricType&lt;/code&gt; (e.g., &lt;code&gt;"temperature"&lt;/code&gt; constant)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;timestamp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If you need cross‑device time‑range queries for a single metric (rare).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; The primary table already supports the latest‑reading query; the GSI is optional and only adds cost if you anticipate many concurrent “latest” reads that could cause hot‑partition reads on the same &lt;code&gt;deviceId&lt;/code&gt;. In most cases the primary table with &lt;code&gt;Limit=1&lt;/code&gt; suffices.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Capacity Mode &amp;amp; Scaling
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;When to use&lt;/th&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;On‑Demand&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unpredictable spikes, easy start‑up, no need to manage capacity.&lt;/td&gt;
&lt;td&gt;Handles 10 k writes/sec automatically; pay per request.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Provisioned + Auto Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Predictable traffic, want to control cost.&lt;/td&gt;
&lt;td&gt;Start with &lt;strong&gt;15,000 RCUs&lt;/strong&gt; and &lt;strong&gt;5,000 WCUs&lt;/strong&gt; (each write of ≤ 1 KB consumes 1 WCU). Enable auto‑scaling target 70 % utilization.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Cost comparison (approx., US East 1, Dec 2025):&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On‑Demand writes: $1.25 per million write request units → ~ $12.5 k/month for 10 k writes/s (≈ 26 M writes/day).
&lt;/li&gt;
&lt;li&gt;Provisioned 5,000 WCUs ≈ $0.65 per WCU‑hour → $2.3 k/month plus auto‑scaling buffer.
On‑Demand is simpler; provisioned can be cheaper if traffic is stable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Mitigating Hot‑Partition Risk
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Uniform &lt;code&gt;deviceId&lt;/code&gt; distribution:&lt;/strong&gt; Ensure device IDs are random (e.g., UUID or hashed).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If a few devices dominate traffic:&lt;/strong&gt; Use &lt;strong&gt;sharding&lt;/strong&gt; – prepend a random shard suffix to &lt;code&gt;deviceId&lt;/code&gt; (e.g., &lt;code&gt;deviceId#shard01&lt;/code&gt;). Store the shard count in a small config table; the application queries all shards and merges results. This spreads write capacity across partitions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Data Retention (TTL)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add a numeric attribute &lt;code&gt;ttl&lt;/code&gt; = &lt;code&gt;timestampEpoch + 30 days&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;DynamoDB TTL&lt;/strong&gt; on this attribute; DynamoDB automatically deletes expired items (typically within 48 h of expiration).
&lt;/li&gt;
&lt;li&gt;No additional Lambda needed, keeping cost low.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Read Performance Optimizations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Projection:&lt;/strong&gt; Keep only needed attributes in the GSI (e.g., &lt;code&gt;temperature&lt;/code&gt;, &lt;code&gt;humidity&lt;/code&gt;, &lt;code&gt;pressure&lt;/code&gt;, &lt;code&gt;timestamp&lt;/code&gt;). This reduces read size and cost.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent vs. eventual reads:&lt;/strong&gt; Use &lt;strong&gt;eventual consistency&lt;/strong&gt; for most queries (cheaper, 0.5 RCU per 4 KB). For the “latest reading” where freshness is critical, use &lt;strong&gt;strongly consistent&lt;/strong&gt; read (1 RCU per 4 KB).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BatchGetItem&lt;/strong&gt; for fetching multiple latest readings across devices in a single call.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7. Auxiliary Services (optional)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS Kinesis Data Streams&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Buffer inbound sensor data, smooth bursty writes, and feed DynamoDB via a Lambda consumer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS Lambda (TTL cleanup)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;If you need deterministic deletion exactly at 30 days, a scheduled Lambda can query items with &lt;code&gt;ttl&lt;/code&gt; nearing expiration and delete them, but DynamoDB TTL is usually sufficient.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amazon CloudWatch Alarms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Monitor &lt;code&gt;ConsumedWriteCapacityUnits&lt;/code&gt;, &lt;code&gt;ThrottledRequests&lt;/code&gt;, and &lt;code&gt;SystemErrors&lt;/code&gt; to trigger scaling or alerts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS Glue / Athena&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;For ad‑hoc analytics on historical data exported to S3 (via DynamoDB Streams → Lambda → S3).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  8. Trade‑offs Summary
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trade‑off&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;On‑Demand vs. Provisioned&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;On‑Demand simplifies ops but can be ~30 % more expensive at steady 10 k writes/s. Provisioned requires capacity planning but can be cheaper with auto‑scaling.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sharding vs. Simplicity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sharding eliminates hot‑partition risk for skewed device traffic but adds complexity in query logic (multiple shards per device).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TTL vs. Lambda cleanup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;TTL is low‑cost, eventual deletion (up to 48 h delay). Lambda gives precise control but adds compute cost.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GSI for latest reading&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Guarantees O(1) read latency even under heavy load, but incurs extra write cost (each write updates the GSI). Often unnecessary if &lt;code&gt;Limit=1&lt;/code&gt; on primary table suffices.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Strong vs. eventual consistency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong reads double read cost; use only where immediate freshness is required.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With this design you achieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fast point‑lookup&lt;/strong&gt; (&lt;code&gt;Query&lt;/code&gt; with &lt;code&gt;deviceId&lt;/code&gt; + &lt;code&gt;Limit=1&lt;/code&gt;, &lt;code&gt;ScanIndexForward=false&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficient time‑range queries&lt;/strong&gt; (&lt;code&gt;Query&lt;/code&gt; with &lt;code&gt;deviceId&lt;/code&gt; and &lt;code&gt;timestamp BETWEEN …&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic 30‑day expiration&lt;/strong&gt; via DynamoDB TTL.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost‑effective high‑throughput writes&lt;/strong&gt; using on‑demand or provisioned capacity with auto‑scaling, plus optional sharding to avoid hot partitions.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>dynamodb</category>
    </item>
    <item>
      <title>Building a Multi‑Region Failover Architecture for a Lambda‑Backed API</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Thu, 04 Dec 2025 09:33:08 +0000</pubDate>
      <link>https://dev.to/codegreen/building-a-multi-region-failover-architecture-for-a-lambda-backed-api-1aae</link>
      <guid>https://dev.to/codegreen/building-a-multi-region-failover-architecture-for-a-lambda-backed-api-1aae</guid>
      <description>&lt;p&gt;Your team runs a critical REST API (API Gateway → Lambda → DynamoDB) in the &lt;code&gt;us-east-1&lt;/code&gt; region.&lt;br&gt;&lt;br&gt;
To meet a 99.99% availability SLA you must design a multi‑region failover solution that automatically routes traffic to a standby deployment in &lt;code&gt;eu-west-1&lt;/code&gt; if the primary region experiences an outage.  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Automatic health‑checking of the primary endpoint.
&lt;/li&gt;
&lt;li&gt;Seamless DNS‑based failover with minimal client impact.
&lt;/li&gt;
&lt;li&gt;Data consistency between the DynamoDB tables in both regions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Include any trade‑offs (e.g., latency, cost, eventual consistency) and a brief diagram description.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario‑Based Lambda Question 4
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Title:&lt;/strong&gt; Multi‑Region Failover Architecture for a Lambda‑Backed API&lt;/p&gt;

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

&lt;h3&gt;
  
  
  1. Automatic Health‑Checking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Route 53 Health Checks&lt;/strong&gt; targeting the API Gateway endpoint (&lt;code&gt;https://api-id.execute-api.us-east-1.amazonaws.com/prod/health&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;Health check type &lt;strong&gt;HTTPS&lt;/strong&gt;, request interval &lt;strong&gt;30 s&lt;/strong&gt;, failure threshold &lt;strong&gt;3&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;CloudWatch alarm&lt;/strong&gt; on the health‑check status for visibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. DNS‑Based Failover
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Route 53 Hosted Zone&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Create an &lt;strong&gt;A (Alias) record&lt;/strong&gt; for &lt;code&gt;api.example.com&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary record&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Alias → API Gateway in &lt;code&gt;us-east-1&lt;/code&gt;. Set &lt;strong&gt;Routing Policy = Failover&lt;/strong&gt;, &lt;strong&gt;Failover Type = Primary&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Secondary record&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Alias → API Gateway in &lt;code&gt;eu-west-1&lt;/code&gt;. Set &lt;strong&gt;Failover Type = Secondary&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TTL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low value (e.g., &lt;strong&gt;30 s&lt;/strong&gt;) to allow quick client re‑resolution after failover.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When the health check fails, Route 53 automatically switches DNS responses to the secondary alias, causing clients to resolve to the standby API with minimal delay.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Data Consistency Between DynamoDB Tables
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB Global Tables (Version 2)&lt;/strong&gt; spanning &lt;code&gt;us-east-1&lt;/code&gt; and &lt;code&gt;eu-west-1&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;Provides &lt;strong&gt;multi‑master, active‑active replication&lt;/strong&gt; with &lt;strong&gt;eventual consistency&lt;/strong&gt; (typically &amp;lt; 1 s replication latency).
&lt;/li&gt;
&lt;li&gt;No additional application code needed; writes in either region are replicated automatically.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Alternative (if Global Tables not viable):&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;DynamoDB Streams&lt;/strong&gt; + &lt;strong&gt;Lambda cross‑region replication&lt;/strong&gt;: stream changes from the primary table to a Lambda in the secondary region that writes to the standby table. This adds extra latency and operational overhead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Trade‑offs
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Consideration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Clients in Europe will see lower latency when routed to &lt;code&gt;eu-west-1&lt;/code&gt;. During normal operation, &lt;code&gt;us-east-1&lt;/code&gt; may be farther for EU users, but DNS failover only occurs on outage.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Global Tables incur additional write/read capacity charges for cross‑region replication. Two API Gateways, Lambdas, and CloudWatch metrics double the baseline cost.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consistency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Global Tables are &lt;strong&gt;eventually consistent&lt;/strong&gt;; a write may not be visible in the other region for up to a few seconds. If strict strong consistency is required, a single‑region design with active‑passive replication (e.g., manual snapshot restore) would be needed, but availability would suffer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Failover Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DNS TTL of 30 s means most clients will switch within ~30 s after health‑check failure. Some long‑lived TCP connections may need to be re‑established.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Using Global Tables is the simplest for data sync; custom stream‑Lambda replication adds operational complexity and monitoring overhead.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  5. Operational Steps Summary
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Deploy the API (API GW + Lambda) in both regions.
&lt;/li&gt;
&lt;li&gt;Enable DynamoDB Global Table across the two regions.
&lt;/li&gt;
&lt;li&gt;Create Route 53 health check for the primary API’s &lt;code&gt;/health&lt;/code&gt; endpoint.
&lt;/li&gt;
&lt;li&gt;Set up failover alias records (&lt;code&gt;api.example.com&lt;/code&gt;) with low TTL.
&lt;/li&gt;
&lt;li&gt;Test failover by manually disabling the primary API (e.g., remove its permission) and verify DNS switches and requests succeed in the secondary region.
&lt;/li&gt;
&lt;li&gt;Monitor CloudWatch metrics for health‑check status, Route 53 failover events, and DynamoDB replication lag.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This architecture satisfies the 99.99 % availability goal with automatic detection, rapid DNS‑based traffic shift, and near‑real‑time data replication.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
    </item>
    <item>
      <title>Implementing Secure API Gateway Lambda Integration with Fine‑Grained IAM</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Thu, 04 Dec 2025 09:10:01 +0000</pubDate>
      <link>https://dev.to/codegreen/implementing-secure-api-gateway-lambda-integration-with-fine-grained-iam-3lg7</link>
      <guid>https://dev.to/codegreen/implementing-secure-api-gateway-lambda-integration-with-fine-grained-iam-3lg7</guid>
      <description>&lt;p&gt;You are building a public REST API that invokes a Go‑based Lambda function via API Gateway (REST API).&lt;br&gt;&lt;br&gt;
The API must meet the following security requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Only authenticated clients with a JWT issued by a custom OAuth2 provider can call the endpoint.
&lt;/li&gt;
&lt;li&gt;The Lambda function should have &lt;strong&gt;least‑privilege&lt;/strong&gt; access: it must read from a specific DynamoDB table and write logs to CloudWatch, but nothing else.
&lt;/li&gt;
&lt;li&gt;The API should enforce &lt;strong&gt;per‑method throttling&lt;/strong&gt; (e.g., 100 RPS for GET, 20 RPS for POST) and protect against injection attacks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Describe the complete configuration you would apply—including API Gateway authorizer, IAM roles/policies, and any additional AWS services—to satisfy these requirements. Highlight any trade‑offs or operational considerations.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. JWT Authorizer (Custom Lambda Authorizer)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Create a Lambda authorizer&lt;/strong&gt; (Go or Python) that receives the &lt;code&gt;Authorization&lt;/code&gt; header, validates the JWT signature against the OAuth2 provider’s JWKS endpoint, checks &lt;code&gt;exp&lt;/code&gt;, &lt;code&gt;aud&lt;/code&gt;, and required scopes.&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Return an IAM policy&lt;/strong&gt; from the authorizer that allows &lt;code&gt;execute-api:Invoke&lt;/code&gt; on the specific API method ARN (e.g., &lt;code&gt;arn:aws:execute-api:region:account-id:api-id/stage/GET/resource&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Configure API Gateway&lt;/strong&gt;: &lt;br&gt;• In the REST API, set &lt;strong&gt;Authorizer&lt;/strong&gt; → &lt;strong&gt;Lambda&lt;/strong&gt; → point to the authorizer function. &lt;br&gt;• Enable &lt;strong&gt;Caching&lt;/strong&gt; (TTL ≈ 300 s) to reduce authorizer invocations for repeated tokens.&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Trade‑off:&lt;/em&gt; Using a Lambda authorizer adds latency (extra Lambda invocation). If latency is critical, consider &lt;strong&gt;Cognito User Pools&lt;/strong&gt; (if you can federate the OAuth2 provider) or &lt;strong&gt;JWT authorizer (HTTP API)&lt;/strong&gt; which is native and faster.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Least‑Privilege IAM Role for the Business Lambda
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Execution Role (attached to the business Lambda):&lt;/strong&gt;&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;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&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;"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;"Allow"&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="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"dynamodb:GetItem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"dynamodb:Query"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"dynamodb:Scan"&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;"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:dynamodb:us-east-1:123456789012:table/AllowedTable"&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;"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;"Allow"&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="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"logs:CreateLogGroup"&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:CreateLogStream"&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:PutLogEvents"&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;"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:logs:us-east-1:123456789012:log-group:/aws/lambda/YourFunction:*"&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. API Gateway Method‑Level Throttling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a Usage Plan (even for a public API you can attach a dummy API key).&lt;/li&gt;
&lt;li&gt;Associate the API stage with the usage plan.&lt;/li&gt;
&lt;li&gt;Set method‑level throttling in the usage plan&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Protection Against Injection Attacks
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technique&lt;/th&gt;
&lt;th&gt;Implementation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Input validation&lt;/td&gt;
&lt;td&gt;Validate request payloads in the Lambda using a JSON schema (e.g., gojsonschema).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS WAF&lt;/td&gt;
&lt;td&gt;Attach a WebACL to the API Gateway REST API. Enable managed rule groups like AWSManagedRulesSQLiRuleSet and AWSManagedRulesCommonRuleSet.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content‑type enforcement&lt;/td&gt;
&lt;td&gt;Require application/json via API Gateway request validator.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Request validation&lt;/td&gt;
&lt;td&gt;Define a model in API Gateway and enable Request Validator for required parameters.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  5. End‑to‑End Flow Summary
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Client sends &lt;code&gt;Authorization: Bearer &amp;lt;JWT&amp;gt;&lt;/code&gt; (and optional &lt;code&gt;x‑api‑key&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;API Gateway invokes the Lambda authorizer → validates JWT → returns IAM policy.&lt;/li&gt;
&lt;li&gt;API Gateway checks method throttling (usage plan) and WAF rules.&lt;/li&gt;
&lt;li&gt;If allowed, the request is forwarded to the business Lambda.&lt;/li&gt;
&lt;li&gt;Business Lambda runs with its least‑privilege role, accesses the specific DynamoDB table, writes logs, and returns a response.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>iam</category>
    </item>
    <item>
      <title>Designing an Exactly‑Once DynamoDB Stream Lambda DynamoDB Pipeline</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Thu, 04 Dec 2025 09:04:19 +0000</pubDate>
      <link>https://dev.to/codegreen/designing-an-exactly-once-dynamodb-stream-lambda-dynamodb-pipeline-2h1a</link>
      <guid>https://dev.to/codegreen/designing-an-exactly-once-dynamodb-stream-lambda-dynamodb-pipeline-2h1a</guid>
      <description>&lt;p&gt;Your team needs to build a data‑processing pipeline that reads records from a DynamoDB stream and writes transformed items to another DynamoDB table.&lt;br&gt;&lt;br&gt;
The Lambda function must guarantee &lt;strong&gt;exactly‑once&lt;/strong&gt; processing even if the function is retried due to failures or throttling.&lt;br&gt;&lt;br&gt;
Explain how you would design the Lambda function and its interaction with DynamoDB to achieve exactly‑once semantics, and list any limitations or edge cases you need to handle.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use DynamoDB Streams with &lt;code&gt;TRIM_HORIZON&lt;/code&gt; and &lt;code&gt;NEW_IMAGE&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable a stream on the source table with the &lt;strong&gt;&lt;code&gt;NEW_IMAGE&lt;/code&gt;&lt;/strong&gt; view type so each record contains the full item after the write.
&lt;/li&gt;
&lt;li&gt;The Lambda event source mapping reads the stream in order per partition key, preserving the sequence.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Idempotent Write Logic&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the target table, include a &lt;strong&gt;deduplication attribute&lt;/strong&gt; (e.g., &lt;code&gt;sourceVersion&lt;/code&gt; or a hash of the source item’s &lt;code&gt;PK+SK+Version&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;When writing, use a &lt;strong&gt;conditional put&lt;/strong&gt; (&lt;code&gt;ConditionExpression: attribute_not_exists(sourceVersion)&lt;/code&gt;) so the write succeeds only if that version hasn’t been processed before.
&lt;/li&gt;
&lt;li&gt;If the condition fails, treat it as a duplicate and simply acknowledge the record.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Leverage DynamoDB Transaction API&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wrap the read‑transform‑write in a &lt;strong&gt;single transaction&lt;/strong&gt; (&lt;code&gt;TransactWriteItems&lt;/code&gt;) that includes:
a) A &lt;strong&gt;condition check&lt;/strong&gt; on the source record’s &lt;code&gt;StreamViewType&lt;/code&gt; version (e.g., &lt;code&gt;attribute_exists(sourceVersion)&lt;/code&gt;) to ensure the source hasn’t changed since the stream event was generated.
b) The &lt;strong&gt;put&lt;/strong&gt; into the destination table with the deduplication attribute.
&lt;/li&gt;
&lt;li&gt;Transactions are atomic; either both succeed or both fail, preventing partial updates.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Handle Retries &amp;amp; Throttling&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure the Lambda &lt;strong&gt;event source mapping&lt;/strong&gt; with a &lt;strong&gt;maximum retry attempts&lt;/strong&gt; (default 5) and a &lt;strong&gt;dead‑letter queue (DLQ)&lt;/strong&gt; for records that still fail.
&lt;/li&gt;
&lt;li&gt;Ensure the function is &lt;strong&gt;idempotent&lt;/strong&gt; (step 2) so retries do not create duplicate target items.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Optional: Use a &lt;code&gt;DynamoDB&lt;/code&gt; &lt;code&gt;UpdateItem&lt;/code&gt; with &lt;code&gt;ADD&lt;/code&gt; on a processed‑set attribute&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For low‑volume streams, maintain a small set of processed stream &lt;code&gt;SequenceNumber&lt;/code&gt;s in a separate “tracker” item.
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;UpdateItem&lt;/code&gt; with &lt;code&gt;ADD&lt;/code&gt; and a condition that the sequence number isn’t already present. This provides an explicit exactly‑once guard without relying on target‑table attributes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Limitations &amp;amp; Edge Cases
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;th&gt;Mitigation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Out‑of‑order processing across shards&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Streams guarantee order &lt;strong&gt;only within a partition key&lt;/strong&gt;. If your logic depends on global ordering, you must add a sequencing layer (e.g., a Kinesis stream).&lt;/td&gt;
&lt;td&gt;Design the pipeline to be order‑agnostic per item, or introduce a downstream ordering service.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stream record expiration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stream records are retained for 24 h (default) – if the Lambda falls behind, records may be lost.&lt;/td&gt;
&lt;td&gt;Set a higher retention (up to 7 days) and monitor &lt;code&gt;IteratorAge&lt;/code&gt; metric; scale Lambda concurrency accordingly.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transaction size limits&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DynamoDB transactions can include up to 25 items and 4 MB total.&lt;/td&gt;
&lt;td&gt;Keep each transaction to a single source‑target pair; batch processing must be split.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Conditional write race&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Two concurrent Lambda invocations for the same source key could both pass the condition check before either writes.&lt;/td&gt;
&lt;td&gt;Use the &lt;strong&gt;transaction&lt;/strong&gt; approach (condition check + put) which is atomic, or include a &lt;strong&gt;unique version&lt;/strong&gt; attribute that changes on every source write.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DLQ handling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Records that end up in the DLQ have not been processed exactly once.&lt;/td&gt;
&lt;td&gt;Implement a manual re‑processing job that inspects the DLQ, applies the same idempotent logic, and moves successful items back to the target table.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Summary Design Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Enable DynamoDB stream (&lt;code&gt;NEW_IMAGE&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;Create Lambda with Go handler that:

&lt;ul&gt;
&lt;li&gt;Parses the stream record.
&lt;/li&gt;
&lt;li&gt;Computes a deterministic deduplication key.
&lt;/li&gt;
&lt;li&gt;Calls &lt;code&gt;TransactWriteItems&lt;/code&gt; with a condition check on the source version and a conditional put into the destination table.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Configure event source mapping: batch size ~ 100, max retries, DLQ (e.g., SQS).
&lt;/li&gt;
&lt;li&gt;Monitor &lt;code&gt;IteratorAge&lt;/code&gt;, &lt;code&gt;ThrottledRequests&lt;/code&gt;, and DLQ length; adjust concurrency or provisioned throughput as needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With this design the pipeline achieves &lt;strong&gt;exactly‑once&lt;/strong&gt; semantics while handling retries, throttling, and potential race conditions.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>dynamodb</category>
    </item>
    <item>
      <title>Reducing Cold‑Start Latency for Go‑Based Lambda Functions Triggered by S3 Events</title>
      <dc:creator>Code Green</dc:creator>
      <pubDate>Thu, 04 Dec 2025 08:59:48 +0000</pubDate>
      <link>https://dev.to/codegreen/reducing-cold-start-latency-for-go-based-lambda-functions-triggered-by-s3-events-2ib4</link>
      <guid>https://dev.to/codegreen/reducing-cold-start-latency-for-go-based-lambda-functions-triggered-by-s3-events-2ib4</guid>
      <description>&lt;p&gt;You have a Go‑based Lambda function that processes events from an S3 bucket (ObjectCreated events).&lt;br&gt;&lt;br&gt;
During peak traffic the function experiences frequent cold starts, causing the overall processing latency to exceed the SLA.&lt;br&gt;&lt;br&gt;
Here are*&lt;em&gt;three&lt;/em&gt;* concrete strategies you can apply to reduce cold‑start latency for this workload, and explain the trade‑offs of each.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Provisioned Concurrency&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;How it works:&lt;/em&gt; Allocate a fixed number of pre‑warmed execution environments for the function. AWS keeps these environments ready, so the first invocations hit a warm container.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Pros:&lt;/em&gt; Near‑zero cold‑start latency; predictable performance.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Cons:&lt;/em&gt; incurs additional cost (charged per GB‑second of provisioned capacity, even when idle); you must size it correctly to avoid over‑provisioning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Package Optimization (Reduce Deployment Package Size)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;How it works:&lt;/em&gt; Build the Go binary with &lt;code&gt;GOOS=linux GOARCH=amd64 CGO_ENABLED=0&lt;/code&gt; and strip debug symbols (&lt;code&gt;-ldflags="-s -w"&lt;/code&gt;). Keep the zip file &amp;lt; 50 MB and move shared libraries to a Lambda Layer.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Pros:&lt;/em&gt; Smaller download/unzip time during container initialization, directly reduces cold‑start duration. No extra cost.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Cons:&lt;/em&gt; Requires build‑pipeline changes; may limit the number of third‑party libraries you can embed; layers add an extra lookup step (though usually negligible).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use an HTTP API Gateway with &lt;em&gt;Lambda @ Edge&lt;/em&gt; (if applicable)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;How it works:&lt;/em&gt; Deploy the function as a Lambda @ Edge function attached to a CloudFront distribution. Edge locations keep the function warm globally, and the first request at each edge is served from a warm container.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Pros:&lt;/em&gt; Cold‑starts are mitigated for geographically distributed clients; can also provide caching at the edge.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Cons:&lt;/em&gt; Only works for request‑response use cases (not suitable for pure S3 event triggers); adds complexity and extra cost (CloudFront + Lambda @ Edge pricing); debugging is more involved.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Summary of Trade‑offs&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;Strategy&lt;/th&gt;
&lt;th&gt;Cost Impact&lt;/th&gt;
&lt;th&gt;Implementation Effort&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Provisioned Concurrency&lt;/td&gt;
&lt;td&gt;Higher (per‑GB‑second)&lt;/td&gt;
&lt;td&gt;Low (just config)&lt;/td&gt;
&lt;td&gt;Strict latency SLA, predictable traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Package Optimization&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Medium (build changes)&lt;/td&gt;
&lt;td&gt;Any workload, especially when cost‑sensitive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda @ Edge&lt;/td&gt;
&lt;td&gt;Higher (CloudFront + Edge)&lt;/td&gt;
&lt;td&gt;High (architecture change)&lt;/td&gt;
&lt;td&gt;Global, latency‑critical front‑end APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Applying &lt;strong&gt;Provisioned Concurrency&lt;/strong&gt; together with &lt;strong&gt;Package Optimization&lt;/strong&gt; usually yields the greatest latency reduction with manageable cost for an S3‑triggered processing pipeline. If the workload is truly global and request‑driven, consider the Lambda @ Edge approach.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
    </item>
  </channel>
</rss>
