<?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: Jun</title>
    <description>The latest articles on DEV Community by Jun (@jun_uen0).</description>
    <link>https://dev.to/jun_uen0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F782615%2F81e91fa3-7309-41af-801d-5c485781aa7e.JPEG</url>
      <title>DEV Community: Jun</title>
      <link>https://dev.to/jun_uen0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jun_uen0"/>
    <language>en</language>
    <item>
      <title>When should you publish a dev post? I counted, and JP vs EN are mirror images</title>
      <dc:creator>Jun</dc:creator>
      <pubDate>Mon, 22 Jun 2026 03:34:26 +0000</pubDate>
      <link>https://dev.to/jun_uen0/when-should-you-publish-a-dev-post-i-counted-and-jp-vs-en-are-mirror-images-2pc7</link>
      <guid>https://dev.to/jun_uen0/when-should-you-publish-a-dev-post-i-counted-and-jp-vs-en-are-mirror-images-2pc7</guid>
      <description>&lt;p&gt;Let me confess something a little creepy.&lt;/p&gt;

&lt;p&gt;I have a habit of peeking at other people's dev posts.&lt;/p&gt;

&lt;p&gt;Not stealing the writing — relax. I run a tiny read-only job that fetches the &lt;em&gt;public&lt;/em&gt; pages on dev.to, Zenn, and Qiita and counts only the boring parts: titles, post times, like counts. Who published what, at what hour, and how far it traveled. Then it tallies the lot.&lt;/p&gt;

&lt;p&gt;The reason is petty: my own posts weren't landing. The &lt;em&gt;content&lt;/em&gt; is already in my hands — so I wanted to know how much the rest, the &lt;strong&gt;when and how you publish&lt;/strong&gt;, actually moves the needle. By the numbers, not by gut.&lt;/p&gt;

&lt;p&gt;So I counted across three platforms. And the conditions that make a post fly turned out to be roughly &lt;strong&gt;mirror images&lt;/strong&gt; between Japan (Zenn / Qiita) and the English-speaking world (dev.to). Here's the story.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, my most important disclaimer
&lt;/h2&gt;

&lt;p&gt;This post is full of numbers, so let me put up a guardrail before any of them.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;correlation, not causation&lt;/strong&gt;. A result like "weekend posts don't do well" could mean the weekend itself is bad — or it could mean people who post on weekends are just dashing something off on the side. The data can't separate those. Please read it that way.&lt;/p&gt;

&lt;p&gt;Also, I only keep &lt;strong&gt;aggregate numbers I computed myself&lt;/strong&gt;. I don't store or reuse anyone's article body (read-only GET, count the features, throw the page away). I peek, but only at the &lt;em&gt;overall shape&lt;/em&gt;. Nobody gets singled out here.&lt;/p&gt;

&lt;p&gt;With that out of the way — four findings I enjoyed.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The best hour to publish is just your readers' time zone
&lt;/h2&gt;

&lt;p&gt;This one came out cleanest.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On &lt;strong&gt;Qiita&lt;/strong&gt;, posts published in the morning win (+32pt in the GOOD group). Midday is +14pt. Evening is -32pt, late night -14pt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zenn&lt;/strong&gt; likes midday too (+27pt). Late night is -15pt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dev.to&lt;/strong&gt; is the exact opposite. Late night &lt;em&gt;Japan time&lt;/em&gt; scores +7pt — Japanese evening is actually weak.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trick is obvious once you see it. dev.to's readers are English-speaking, mostly US. &lt;strong&gt;Late night in Japan is the US working day.&lt;/strong&gt; Zenn and Qiita readers are in Japan, so the Japanese morning-to-midday slot just works.&lt;/p&gt;

&lt;p&gt;So the right answer to "when should I publish?" isn't the platform — it's &lt;strong&gt;which time zone your readers live in&lt;/strong&gt;. English version in the dead of Japanese night; Japanese version in the Japanese morning. Obvious in hindsight. Still satisfying to watch it fall out of the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. On weekends, Japanese posts die
&lt;/h2&gt;

&lt;p&gt;This one honestly spooked me a little.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zenn posts published on weekends score -54pt.&lt;/strong&gt; Only 15% of the GOOD group went out on a weekend; 69% of the BAD group did. &lt;strong&gt;Qiita is -25pt&lt;/strong&gt; too.&lt;/p&gt;

&lt;p&gt;Meanwhile &lt;strong&gt;dev.to is -6pt&lt;/strong&gt; — basically noise.&lt;/p&gt;

&lt;p&gt;The funny part: the Japanese platforms have &lt;em&gt;more&lt;/em&gt; weekend posting, yet those posts don't travel. Everyone writes on Saturday, ships on Saturday, and sinks. Sound familiar? (It does to me.)&lt;/p&gt;

&lt;p&gt;This follows straight from finding 1: Japanese engineers seem to read dev posts &lt;strong&gt;around the weekday commute and the start of the workday&lt;/strong&gt;. On weekends they're the ones writing code, not reading about it.&lt;/p&gt;

&lt;p&gt;And this is the textbook "correlation, not causation" trap. Weekend posts might simply be lazier than the ones people sweat over on a Tuesday. Maybe the day isn't cursed at all. But the direction is unambiguous: &lt;strong&gt;shipping a Japanese dev post on the weekend is playing on hard mode.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Numbers and colons travel differently across the ocean
&lt;/h2&gt;

&lt;p&gt;Title craft splits by platform too.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A digit in a Zenn title costs -35pt.&lt;/strong&gt; "3 ways to…", "the 2026 edition" — those just don't fly.&lt;/li&gt;
&lt;li&gt;On &lt;strong&gt;dev.to a digit is basically nothing&lt;/strong&gt; (-2pt). Don't sweat it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The colon format ("X: Y") is a headwind on all three&lt;/strong&gt; (dev.to -14pt, Zenn -15pt). I thought it looked sharp. Readers disagree.&lt;/li&gt;
&lt;li&gt;For good measure, &lt;strong&gt;Zenn dislikes bracket titles&lt;/strong&gt; (【】, []) at -23pt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The only thing mildly positive everywhere was the &lt;strong&gt;question-form title&lt;/strong&gt; (dev.to +7pt, Zenn +8pt, Qiita +7pt). Ask, and people can't help clicking. This post's title is a question. Subtle, I know.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Shorter usually wins
&lt;/h2&gt;

&lt;p&gt;Last one is simple. &lt;strong&gt;Shorter posts travel further.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Zenn's GOOD group runs about 6,700 characters in the body; the BAD group about 11,700. The posts that &lt;em&gt;landed&lt;/em&gt; are nearly &lt;strong&gt;half the length&lt;/strong&gt;. Titles too — all three platforms have shorter titles in the GOOD group.&lt;/p&gt;

&lt;p&gt;"Write more and it'll get through" turned out to be a fantasy. My hands are slowing down as I type this. (This very post could probably stand to be cut.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The four times the numbers almost fooled me
&lt;/h2&gt;

&lt;p&gt;I've been saying "X works" — but when you tally things, &lt;strong&gt;fake correlations show up constantly.&lt;/strong&gt; Here are the four I tripped over. Without this section, this whole post is just a pile of dangerous claims.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Emojis work — no they don't.&lt;/strong&gt;&lt;br&gt;
On Zenn, "title has an emoji" was &lt;strong&gt;100% in both&lt;/strong&gt; the winners and the losers. For a second I thought "emojis are mandatory?!" — but Zenn &lt;em&gt;requires&lt;/em&gt; an emoji in the frontmatter. &lt;strong&gt;If everyone does it, it can't explain a difference.&lt;/strong&gt; A metric that's structurally saturated looks like signal and is pure noise. Writing "emojis work" would have been a great way to embarrass myself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. "Japan engages more" is a misread.&lt;/strong&gt;&lt;br&gt;
By median likes, dev.to is 1 and Zenn is 3. Tempting to read "Japan engages harder!" But that's just &lt;strong&gt;different platform sizes and different like-cultures&lt;/strong&gt; — comparing absolute values across countries is meaningless. Look at the shape. Zenn's top 10% reaches 74 likes; dev.to's reaches 13. Same word "viral," totally different ceiling. &lt;strong&gt;Never brawl with raw absolute numbers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The sample is small.&lt;/strong&gt;&lt;br&gt;
Zenn's winning group is &lt;em&gt;26 posts&lt;/em&gt;. Shouting "-54pt!" off 26 posts is, frankly, scary. Each platform has its own cutoff and its own sample size (Zenn 26, Qiita 28). So I don't call any of this a "law" — I file it as an &lt;strong&gt;observed hypothesis&lt;/strong&gt; and only promote the ones that reproduce in another week. A number seen once is still a horoscope.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. And all of it is just correlation.&lt;/strong&gt;&lt;br&gt;
I'll say it one more time. Whether weekends are weak, whether long posts are weak — the data can't tell me if the &lt;em&gt;condition&lt;/em&gt; is bad or if the &lt;em&gt;people&lt;/em&gt; who post under it are just careless. Numbers point a direction; they don't guarantee the reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  Counting kills your instincts, one at a time
&lt;/h2&gt;

&lt;p&gt;What it really taught me is that this was never a hunt for a growth hack.&lt;/p&gt;

&lt;p&gt;It was the opposite — &lt;strong&gt;a slow execution of every gut feeling I'd been carrying.&lt;/strong&gt; "Surely emojis help." "Surely a digit gets the click." One by one, the things I vaguely believed got quietly voted down as I counted.&lt;/p&gt;

&lt;p&gt;What survived is a few plain lines. &lt;strong&gt;English version in the dead of Japanese night; Japanese version on a weekday morning. Short, and ideally a question.&lt;/strong&gt; That's it.&lt;/p&gt;

&lt;p&gt;No secret hack. But I got to drop a stack of instincts I'd been trusting without ever checking them. Before you fight on content, at least don't trip over your own feet in the delivery. Next time your post mysteriously won't land — go count. (And lose your instincts one at a time, same as I did.)&lt;/p&gt;

</description>
      <category>blogging</category>
      <category>dataanalysis</category>
      <category>devto</category>
      <category>career</category>
    </item>
    <item>
      <title>Playing hide-and-seek with an API key our CFO's Claude Code kept hiding</title>
      <dc:creator>Jun</dc:creator>
      <pubDate>Thu, 18 Jun 2026 01:23:22 +0000</pubDate>
      <link>https://dev.to/jun_uen0/playing-hide-and-seek-with-an-api-key-our-cfos-claude-code-kept-hiding-job</link>
      <guid>https://dev.to/jun_uen0/playing-hide-and-seek-with-an-api-key-our-cfos-claude-code-kept-hiding-job</guid>
      <description>&lt;p&gt;There's a B2B SaaS that a non-engineer executive built &lt;strong&gt;all the way to production in two days&lt;/strong&gt;, by handing everything to an AI.&lt;/p&gt;

&lt;p&gt;Real customers use it. It works. Features ship fast. It's genuinely impressive.&lt;/p&gt;

&lt;p&gt;And then I got handed the infra and the ops for it. I'm the guy who walks the "it's running in production" code path one step at a time. Treasure hunt, minefield sweep — somewhere in between.&lt;/p&gt;

&lt;p&gt;Today's story is about one of those steps: &lt;strong&gt;where the secrets (API keys and friends) were kept&lt;/strong&gt;, and the game of hide-and-seek that played out there.&lt;/p&gt;

&lt;p&gt;Here's the punchline up front: every time I said "uh, that's dangerous," the secret's hiding spot &lt;strong&gt;moved house&lt;/strong&gt;. And every time it moved, I got the look that says "there, now it's safe, right?"&lt;/p&gt;

&lt;p&gt;Hiding something and securing something are not the same thing. That's the whole article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stage one: hardcoded in the source
&lt;/h2&gt;

&lt;p&gt;The first one I found was a fastball right down the middle.&lt;/p&gt;

&lt;p&gt;The API key was &lt;strong&gt;written straight into the source code&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(the real key string)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# ...right there in the open
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Classic vibe coding (= you give an AI a fuzzy instruction and it builds the thing). Getting it to &lt;em&gt;run&lt;/em&gt; is the only priority, so it lands on the shortest path that works — embed the value as-is. The AI happily emits "code that runs"; it just won't emit "code that treats a secret like a secret" unless you ask.&lt;/p&gt;

&lt;p&gt;So I say my piece: "Hardcoding the key in the source is bad. One look at the repo and it's leaked."&lt;/p&gt;

&lt;p&gt;The exec, bless them, was agreeable and fixed it right away. Fixed it, sure — but —&lt;/p&gt;

&lt;h2&gt;
  
  
  Stage two: relocated to the README
&lt;/h2&gt;

&lt;p&gt;They said it was fixed, so I checked. The key was gone from the source. Oh, nice.&lt;/p&gt;

&lt;p&gt;Except — &lt;strong&gt;it was now in the README&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As a "setup step." Very helpfully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Setup
1. Clone the repository
2. Set the following key: (the real key string)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;…you see it, right? The secret &lt;strong&gt;just moved from the source to the instructions&lt;/strong&gt; — it's still sitting inside the repo, not one millimeter less exposed. If anything, what was buried deep in the code got &lt;strong&gt;promoted to a prime, front-and-center spot&lt;/strong&gt; in the document everyone reads first.&lt;/p&gt;

&lt;p&gt;In hide-and-seek terms: it came out of the closet and is now standing in the entryway. Easier to find. Great job.&lt;/p&gt;

&lt;p&gt;I get the feeling of accomplishment — "I removed it from the code." I do. But in secret-management land, &lt;strong&gt;the moment it's inside the repo, it's already game over&lt;/strong&gt;. You've handed it to everyone who clones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stage three: stored in the DB (progress!), but…
&lt;/h2&gt;

&lt;p&gt;"The README is no good either. The point is: don't put it inside the repo at all." I explained it once more.&lt;/p&gt;

&lt;p&gt;This time they really thought about it, and the next time I looked, the key was &lt;strong&gt;stored in the database&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Which — directionally — is correct. It left the repo. No secret in the code, none in the README. Progress. I clapped. Genuinely.&lt;/p&gt;

&lt;p&gt;I did. But.&lt;/p&gt;

&lt;p&gt;When I actually peeked inside, the value was sitting there &lt;strong&gt;in plaintext&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No encryption, no masking, nothing. Open the table and anyone can read it — the key string, just sitting there on its throne.&lt;/p&gt;

&lt;p&gt;Putting it in the DB does not equal safe. &lt;strong&gt;The location changed; the secret was never once actually concealed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the source → in the docs → in the DB (still plaintext). The hiding spot took a three-stop trip and finally made it "outside" — but it hasn't moved a single step closer to "concealed." The seeker in this game is still looking in exactly the same place.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Hiding" and "concealing" are different things
&lt;/h2&gt;

&lt;p&gt;I'm not telling this to laugh at the culprit (= the exec). Honestly, &lt;strong&gt;it's a really natural instinct&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Human intuition goes like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you put it somewhere out of sight, it's safe.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The closet, the attic, a box pretending to be a safe. Make it invisible and you feel like you've protected it. In the physical world that's half true.&lt;/p&gt;

&lt;p&gt;But in software secret management, that intuition slips. The question isn't "is it hard to see," it's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Does putting it there keep it out of the distributable (the repo)?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Is read access actually narrowed to only the people who need it?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Even if it's read, is the content encrypted so it's meaningless?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's what matters. Moving the location is "hiding." Only when you satisfy the above do you "conceal." Take it on a three-city tour and, if it never once meets the bar for concealment, the game of hide-and-seek never ends.&lt;/p&gt;

&lt;h2&gt;
  
  
  So where &lt;em&gt;should&lt;/em&gt; it live?
&lt;/h2&gt;

&lt;p&gt;Roughly, this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Don't put secrets in the code or in the repo&lt;/strong&gt; (hardcoding, README, committed config files — all out). The code should know only the secret's &lt;em&gt;name&lt;/em&gt;, never its value.&lt;/li&gt;
&lt;li&gt;Inject the value &lt;strong&gt;from outside the runtime&lt;/strong&gt; — environment variables, or a secrets manager (a vault built for exactly this).&lt;/li&gt;
&lt;li&gt;If you absolutely must keep it in the DB, &lt;strong&gt;store it encrypted&lt;/strong&gt;. Plaintext means "if the DB leaks, everything leaks."&lt;/li&gt;
&lt;li&gt;And &lt;strong&gt;rotate any key that might have leaked&lt;/strong&gt;. A key that ever sat in plaintext in a repo or a log is contaminated; treat it that way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This SaaS is about to launch, so I tackled the secrets first. We also had an external red team review the source for vulnerabilities, and that pass is done. Secrets are "leak once and it's over," so they go ahead of refactoring and tests — order-wise, this was the thing to knock out first.&lt;/p&gt;

&lt;p&gt;Meanwhile, the obviously-should-be-refactored code and the gaping lack of tests are, for now, &lt;strong&gt;left exactly as they are&lt;/strong&gt;. Because, well, it works. After launch we'll clean it up little by little, update by update. The CFO charges ahead building features; I follow behind sweeping up bugs. That's the split, and right now we're in the just-ship-it phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  The most interesting part: it happened on Opus 4.8
&lt;/h2&gt;

&lt;p&gt;Read this far and you're thinking "well, a non-engineer built it, so sure." I thought so too.&lt;/p&gt;

&lt;p&gt;But here's what made this one genuinely interesting.&lt;/p&gt;

&lt;p&gt;This exec &lt;strong&gt;runs the top-tier AI plan, constantly&lt;/strong&gt; — the smartest current model (Opus 4.8), on the highest tier. By any reasonable expectation, this kind of rookie mistake shouldn't happen with that gear.&lt;/p&gt;

&lt;p&gt;And yet it did. The secret got hardcoded, moved to the README, and landed in the DB in plaintext. &lt;strong&gt;Even with the strongest tool in hand.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's not that the AI is bad. A smart model emits "code that runs" in an instant. It does — but &lt;strong&gt;what counts as a secret, and where it should live&lt;/strong&gt;, only gets satisfied once &lt;em&gt;you&lt;/em&gt; ask for it. Don't ask, and it will cheerfully, brilliantly, help you drop a plaintext secret into your DB.&lt;/p&gt;

&lt;p&gt;In other words —&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Even with the smartest model, if the operator doesn't know what to protect, intelligence doesn't convert into safety.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The capability of the tool and the safety of the result are on different axes. The same way "this knife is sharp" and "you didn't cut your finger" are two different sentences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"Building" got fast; "treating a secret as a secret" is a separate skill.&lt;/strong&gt; Even in an era where a non-engineer ships to prod in two days, this part doesn't fill itself in unless you ask. The brighter the light, the sharper the shadow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Moving the hiding spot is "hiding," not "concealing."&lt;/strong&gt; The moment you feel accomplished about relocating it is your cue to stop and look again.&lt;/li&gt;
&lt;li&gt;The reviewer's lens, when you inherit something, isn't "does it work" — it's &lt;strong&gt;"how could it leak."&lt;/strong&gt; The more it's running happily in production, the more likely a plaintext key is enthroned behind it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Even the smartest top-tier model won't save you when it can fail, it fails.&lt;/strong&gt; Tool capability and output safety are different axes; intelligence converts to safety only when you ask "what are we protecting."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A non-engineer shipping to production is genuinely amazing. I'm not knocking it.&lt;/p&gt;

&lt;p&gt;It's just that &lt;strong&gt;a secret belongs not in an "invisible place" but in the "right place."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before you stuff it in the closet and relax — take one more look: is it visible from the entryway? Stay safe out there.&lt;/p&gt;

</description>
      <category>security</category>
      <category>secretmanagement</category>
      <category>ai</category>
      <category>devops</category>
    </item>
    <item>
      <title>CPU and DB were bored, yet every site timed out: a slow-read bot that starved Apache's workers</title>
      <dc:creator>Jun</dc:creator>
      <pubDate>Mon, 15 Jun 2026 11:47:23 +0000</pubDate>
      <link>https://dev.to/jun_uen0/cpu-and-db-were-bored-yet-every-site-timed-out-a-slow-read-bot-that-starved-apaches-workers-539j</link>
      <guid>https://dev.to/jun_uen0/cpu-and-db-were-bored-yet-every-site-timed-out-a-slow-read-bot-that-starved-apaches-workers-539j</guid>
      <description>&lt;p&gt;One morning, a bunch of EC shops sharing a single server all tripped their monitors at once with "response timeout."&lt;br&gt;
Let me be honest up front: the outage itself self-recovered in about five minutes. There's no heroic recovery scene here.&lt;br&gt;
The real story is not those five minutes. It's &lt;strong&gt;how I chased down the creepy part: every usual suspect was innocent, yet the sites were down.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The stage: one shared web server (Apache prefork) hosting dozens of EC shops.&lt;br&gt;
If you run something like this, your stomach already hurts. One shop's trouble drags the neighbors down with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  One morning, every shop's monitor went red at once
&lt;/h2&gt;

&lt;p&gt;The alerts fired together. Multiple shops, same instant, "socket timeout."&lt;br&gt;
When every shop on a shared box dies simultaneously, your first suspect is "the foundation died" — CPU, memory, DB, that sort of thing.&lt;/p&gt;

&lt;p&gt;Except when I looked, something was off.&lt;br&gt;
The sites were down, but the server was perfectly healthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every usual suspect was innocent
&lt;/h2&gt;

&lt;p&gt;I ruled them out one by one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU: 84% idle. Bored.&lt;/li&gt;
&lt;li&gt;DB: not saturated even at peak. Not the bottleneck.&lt;/li&gt;
&lt;li&gt;Memory: no sign of the OOM killer. No process restarts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every classic load-trouble suspect came back clean.&lt;br&gt;
And yet the monitor kept returning "socket timeout" — meaning &lt;strong&gt;the TCP connection was being established, but nothing came back after that.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's when something nagged at the back of my mind.&lt;br&gt;
If CPU and DB have headroom and memory is fine, then what's running out isn't "compute" — it's &lt;strong&gt;the slots that serve responses.&lt;/strong&gt;&lt;br&gt;
In Apache prefork terms, that's the number of worker processes.&lt;/p&gt;

&lt;h2&gt;
  
  
  My trusted error.log was, in fact, dead
&lt;/h2&gt;

&lt;p&gt;"If we hit MaxRequestWorkers, error.log would say so."&lt;br&gt;
I opened the global error.log expecting that line, and did a double take.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nothing. Not a word.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Digging in, the culprit was the logging pipeline.&lt;br&gt;
ErrorLog was piped to syslog, but the fixed tag I'd attached didn't match rsyslog's routing regex.&lt;br&gt;
As a result, server-scope errors (server-wide, not per-VirtualHost) landed nowhere and vanished into thin air.&lt;br&gt;
Even the one line I wanted most right now — "reached MaxRequestWorkers" — simply wasn't there.&lt;/p&gt;

&lt;p&gt;This is the quiet but scariest part of the whole thing.&lt;br&gt;
In the middle of an incident, the instrument I was relying on wasn't even plugged in.&lt;br&gt;
(I fixed the routing side afterward so server-scope errors are retained. More on that at the end.)&lt;/p&gt;

&lt;h2&gt;
  
  
  I sorted the access log by %D and felt a chill
&lt;/h2&gt;

&lt;p&gt;With error.log dead, I went back to the log that was still alive: the access log.&lt;br&gt;
What saved me was the response-time field (&lt;code&gt;%D&lt;/code&gt;, in microseconds).&lt;/p&gt;

&lt;p&gt;Things invisible when you aggregate by request count show up the moment you sort by &lt;code&gt;%D&lt;/code&gt;.&lt;br&gt;
&lt;strong&gt;159 requests had taken 15+ seconds each. The worst held a worker hostage for 17 minutes (1040 seconds).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Seventeen minutes, for a single web request. Normally we live in milliseconds, or seconds at worst. This was minutes.&lt;br&gt;
And all of them targeted &lt;strong&gt;one single shop, from one single IP.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Count-based aggregation will never float this kind of attacker to the top.&lt;br&gt;
That was the biggest lesson of the day, so I'll put it in bold.&lt;br&gt;
&lt;strong&gt;To find a stall, sort by time spent (%D), not by request count.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The culprit wasn't "the one making lots of requests"
&lt;/h2&gt;

&lt;p&gt;The IP turned out to belong to an overseas commercial proxy / scraping vendor — spoofing an old Chrome UA, pretending to be a browser.&lt;br&gt;
And here's the nastiest part.&lt;/p&gt;

&lt;p&gt;It sent 217 requests over about 8 minutes — roughly 0.45 req/sec. &lt;strong&gt;Low, if anything.&lt;/strong&gt;&lt;br&gt;
That slid right through the connlimit/hashlimit I had in place (drop above 20 concurrent connections or above 1 req/sec).&lt;br&gt;
Ordinary rate limits are built to catch "too fast," so they were useless against "deliberately slow."&lt;/p&gt;

&lt;p&gt;What was it doing?&lt;br&gt;
It fired requests promptly, but &lt;strong&gt;deliberately read back the response only in tiny dribbles.&lt;/strong&gt;&lt;br&gt;
A worker can't be released until the response is fully received, so each one held a slot for 10, 15 minutes.&lt;br&gt;
Do that with many requests at once, and prefork workers fill up one by one until you hit the ceiling (128) — and at that moment every shop's slots are gone.&lt;br&gt;
The foundation (CPU/DB) stays idle the whole time while the sites go down. That's the creepy part, explained.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;response-side version&lt;/strong&gt; of the well-known slowloris (which dribbles out &lt;em&gt;requests&lt;/em&gt; to occupy workers).&lt;br&gt;
It's the family known as low-and-slow — it hits you with "slow," not "fast."&lt;br&gt;
There's no flashy traffic spike, so staring at load graphs won't reveal it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I did on the spot (stopgap)
&lt;/h2&gt;

&lt;p&gt;Once the culprit was clear, I stopped the bleeding first.&lt;br&gt;
The action was simple: &lt;strong&gt;immediately block that single IP.&lt;/strong&gt;&lt;br&gt;
Concretely, one DROP line at the top of the firewall (iptables). I backed up the pre-change state just in case, then added it, and confirmed the collateral shops were serving 200s again.&lt;/p&gt;

&lt;p&gt;But let me be honest here.&lt;br&gt;
This is &lt;strong&gt;just swatting the hand that's hitting you right now&lt;/strong&gt; — not a permanent fix.&lt;br&gt;
The vendor rotates IPs, so IP blocking inevitably becomes whack-a-mole.&lt;br&gt;
And the commonly suggested &lt;code&gt;mod_reqtimeout&lt;/code&gt; watches the case where the &lt;em&gt;request side&lt;/em&gt; is slow (the original slowloris). The case here — the &lt;strong&gt;response-reading side&lt;/strong&gt; being deliberately slow — can't be caught by a request-side timeout.&lt;br&gt;
It's the same reason a simple rate limit got slipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real fix is "a front layer that absorbs fast and slow," I think
&lt;/h2&gt;

&lt;p&gt;From here on, this is not what I actually did, but &lt;strong&gt;the conclusion / the homework&lt;/strong&gt; (I haven't deployed it yet, honestly).&lt;/p&gt;

&lt;p&gt;As long as bare prefork Apache speaks dynamic content directly, the structure itself — "a worker is held until the client finishes reading the response" — never goes away.&lt;br&gt;
So the sensible fix is to put &lt;strong&gt;a front layer that buffers the response&lt;/strong&gt; in front of Apache.&lt;br&gt;
A CDN or reverse proxy receives the full response first, then patiently babysits the slow client on its own.&lt;br&gt;
That way the Apache worker is freed the moment it has flushed the response, and "slow clients" can no longer take slots hostage.&lt;br&gt;
A complementary output-side / idle timeout (cutting off no-progress while streaming a response) helps too.&lt;/p&gt;

&lt;p&gt;In short: &lt;strong&gt;let the front layer, where slots are plentiful, deal with slow clients — not Apache, where slots are precious.&lt;/strong&gt; That's the structural answer, the way I see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what did I actually learn
&lt;/h2&gt;

&lt;p&gt;Not crypto, not algorithms — three humble but effective takeaways.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. If you have CPU/DB headroom but still get socket timeouts, suspect worker/connection exhaustion.&lt;/strong&gt;&lt;br&gt;
Look at the free slots in the worker pool, not the load graph. Resources can be plentiful while "slots" run dry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Hunt stalls by time spent (%D), not by request count.&lt;/strong&gt;&lt;br&gt;
Low-rate low-and-slow won't appear in count aggregation. Sort by &lt;code&gt;%D&lt;/code&gt; and it finally shows its face.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Check that your monitoring logs themselves are alive — in peacetime.&lt;/strong&gt;&lt;br&gt;
"error.log happened to be dead exactly during the incident" is not funny. On a quiet day, make sure your instruments aren't silently dropping into the void. This one stung the most.&lt;/p&gt;

&lt;p&gt;It's precisely because it isn't a flashy attack that it's so easy to miss.&lt;br&gt;
Are the slots in your worker pool actually free right now?&lt;br&gt;
Watch out for the customer who makes few requests but overstays forever.&lt;/p&gt;

</description>
      <category>apache</category>
      <category>security</category>
      <category>sre</category>
      <category>webperf</category>
    </item>
    <item>
      <title>How a Slow Office VPN Led Me to File a US Patent</title>
      <dc:creator>Jun</dc:creator>
      <pubDate>Mon, 08 Jun 2026 06:18:03 +0000</pubDate>
      <link>https://dev.to/jun_uen0/how-a-slow-office-vpn-led-me-to-file-a-us-patent-2gb3</link>
      <guid>https://dev.to/jun_uen0/how-a-slow-office-vpn-led-me-to-file-a-us-patent-2gb3</guid>
      <description>&lt;p&gt;This is the story of how a mundane complaint — "the VPN is slow" — turned into a US patent application. Not a granted patent. An &lt;em&gt;application&lt;/em&gt;. I want to be precise about that from the start, because the distance between the two is the whole point of this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  It started with a slow VPN
&lt;/h2&gt;

&lt;p&gt;The company I work for had an internal VPN that everyone routed through. It lived in the Tokyo office, it was old, and it was not something I built. Then the complaints started arriving — from a lot of people, all saying the same thing: it's slow.&lt;/p&gt;

&lt;p&gt;I work from Thailand most of the time. That detail matters. If that aging box in Tokyo had fallen over, I would have been the person furthest from the power button, in the worst position to fix it. A slow VPN is annoying. An unreachable VPN, when you're a few thousand kilometers away, is a real problem.&lt;/p&gt;

&lt;p&gt;So I started moving it to the cloud. I stood up a WireGuard VPN — modern, fast, and something I could actually reason about and operate remotely instead of inheriting a black box.&lt;/p&gt;

&lt;h2&gt;
  
  
  Down the WireGuard rabbit hole
&lt;/h2&gt;

&lt;p&gt;Around that time I was deep into building my own iPhone apps. So the cloud migration turned into a personal project on the side: I built my own server and wired WireGuard into an iPhone app of my own. And to do that properly, I started studying how WireGuard actually works under the hood — the Noise protocol, the handshake, the key exchange.&lt;/p&gt;

&lt;p&gt;That study is where everything else came from. I wasn't trying to invent anything. I was just trying to understand the thing I was now responsible for.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SYN flood that primed my brain
&lt;/h2&gt;

&lt;p&gt;Not long before, the same company had been hit with a SYN flood attack. If you've dealt with one, you know it lodges the mechanics of connection handshakes firmly in your head — the back-and-forth, the round trips, the cost of every "hello" before any real data moves.&lt;/p&gt;

&lt;p&gt;So I had handshakes on the brain. And then, reading through how WireGuard establishes a session, a thought stopped me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Wait — does it really handshake &lt;em&gt;every single time&lt;/em&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The club-stamp idea
&lt;/h2&gt;

&lt;p&gt;Here's the analogy that made it click for me.&lt;/p&gt;

&lt;p&gt;Think about getting into a club. The first time, there's a whole process: they check your ID, you pay the cover. But once they stamp your hand, you can walk back in again and again — no re-checking every time — until the stamp wears off.&lt;/p&gt;

&lt;p&gt;HTTPS already does something like this. The first connection does the expensive handshake; later ones can resume more cheaply. So I wondered: why can't a VPN handshake work the same way? Do the full handshake on the &lt;em&gt;first&lt;/em&gt; connection, and from the second connection onward, present a kind of token — a stamp — and walk straight in. With an expiry, of course.&lt;/p&gt;

&lt;p&gt;That's the essence of it: a zero round-trip (0-RTT) handshake. The first session sets things up and hands the client a one-time "re-entry" credential. The next session uses that credential to establish a provisional session key on the very first message, instead of paying for another full round trip. After it's used, the server destroys it, so the stamp can't be replayed.&lt;/p&gt;

&lt;p&gt;I'm keeping the cryptography deliberately light here — this is a story about a journey, not a spec. But that "club stamp for VPNs" was the idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Wait... can I patent this?"
&lt;/h2&gt;

&lt;p&gt;The first thing I did was check whether someone had already done it. I went looking for prior art: QUIC's crypto, TLS 1.3's 0-RTT, NoiseSocket, and a pile of academic work. I searched patent databases for 0-RTT key exchange on WireGuard and Noise.&lt;/p&gt;

&lt;p&gt;I found nothing. Zero prior patents for a cached-ephemeral-key 0-RTT handshake on WireGuard.&lt;/p&gt;

&lt;p&gt;That's the moment the question shifted from "is this a neat idea?" to "wait — could I actually patent this?"&lt;/p&gt;

&lt;h2&gt;
  
  
  Filing it myself, solo
&lt;/h2&gt;

&lt;p&gt;I expected the answer to be: hire a patent attorney, spend a small fortune, wait. The quotes I gathered for the full attorney route ran into the thousands of dollars, easily five figures by the time you add drafting and prosecution.&lt;/p&gt;

&lt;p&gt;I went a different way. &lt;strong&gt;I filed it myself, without hiring a patent attorney.&lt;/strong&gt; A few things made that possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The design was already done.&lt;/strong&gt; I had written up the full cryptographic flow while studying WireGuard, so the hard intellectual work — the part you'd normally pay an attorney to extract from you — already existed in my own documents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-LLM review.&lt;/strong&gt; I used several different LLMs (Claude, ChatGPT, Gemini, and others) to review and stress-test the specification and claims from different angles, instead of a single human reviewer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Micro-entity status.&lt;/strong&gt; As a solo inventor under the income threshold, USPTO fees drop to a few hundred dollars rather than thousands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct non-provisional.&lt;/strong&gt; I initially planned to file a cheap provisional first, then convert it within 12 months. In the end I filed the non-provisional directly, since the spec and drawings were ready.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The identity verification was its own small adventure. I went through ID.me and ended up on an online meeting with a US-side representative to confirm I was who I said I was. It cost real money along the way, and the realistic timeline I was warned about is long — examination and a potential grant are measured in &lt;em&gt;years&lt;/em&gt;, on the order of two and up.&lt;/p&gt;

&lt;p&gt;In March 2026 I filed it with the USPTO — "Zero Round-Trip WireGuard Handshake Method and System Using Cached Ephemeral Keys." Sole inventor. Filed by me.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually learned
&lt;/h2&gt;

&lt;p&gt;The thing I want to leave you with isn't the cryptography. It's this: &lt;strong&gt;filing a patent is something one person can do.&lt;/strong&gt; I assumed it required a firm, a budget, and permission. It required a real idea, documentation I'd already written for my own understanding, and a willingness to read the rules carefully.&lt;/p&gt;

&lt;p&gt;And the second thing: &lt;strong&gt;filing is the start, not the finish.&lt;/strong&gt; An application is not a granted patent. Mine is sitting in the queue at the USPTO, and it'll be years before I know whether it becomes a real, granted patent — or gets rejected. I haven't "gotten a patent." I've &lt;em&gt;filed&lt;/em&gt; one. That distinction is easy to blur and worth keeping honest.&lt;/p&gt;

&lt;p&gt;It all started because a VPN was slow and I happened to be the wrong distance away to ignore it.&lt;/p&gt;

</description>
      <category>wireguard</category>
      <category>vpn</category>
      <category>cryptography</category>
      <category>security</category>
    </item>
    <item>
      <title>Create an ECS Fargate Service Step by Step</title>
      <dc:creator>Jun</dc:creator>
      <pubDate>Sat, 06 Jun 2026 01:40:34 +0000</pubDate>
      <link>https://dev.to/jun_uen0/create-an-ecs-fargate-service-step-by-step-1a7d</link>
      <guid>https://dev.to/jun_uen0/create-an-ecs-fargate-service-step-by-step-1a7d</guid>
      <description>&lt;h2&gt;
  
  
  Prepare Docker Image at ECR
&lt;/h2&gt;

&lt;p&gt;If you don't have an image at ECR, please check this article and get it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/jun_uen0/push-docker-image-to-aws-ecr-fb2"&gt;Push Docker image to AWS ECR&lt;/a&gt;&lt;br&gt;
In this article, I use React app image.&lt;/p&gt;

&lt;h2&gt;
  
  
  About ECS
&lt;/h2&gt;

&lt;p&gt;AWS Elastic Container Service &lt;br&gt;
It's a highly scalable and fast container management service.&lt;/p&gt;

&lt;p&gt;Terminologies in ECS&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Task / Task Definition: For setting container&lt;/li&gt;
&lt;li&gt;Service: For setting tasks, auto-scaling, VPC, etc&lt;/li&gt;
&lt;li&gt;Cluster: The cluster of services&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hands-On Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create ECS Cluster&lt;/li&gt;
&lt;li&gt;Create ECS Task Definition&lt;/li&gt;
&lt;li&gt;Create ECS Service&lt;/li&gt;
&lt;li&gt;Confirm ECS Fargate running&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  1. Create ECS Cluster
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;ECS Cluster is a cluster of services that is EC3 instances. But no one can control the EC2 via SSH access because each EC2 instance is hidden.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Select "Create Cluster" at the ECS console&lt;/li&gt;
&lt;li&gt;Select "Only net-working (Fargate)"&lt;/li&gt;
&lt;li&gt;Name cluster&lt;/li&gt;
&lt;li&gt;Create VPC (optional)&lt;/li&gt;
&lt;li&gt;Select "Create"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;※ Wait 1 or 2 minutes.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Create ECS Task Definition
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Task is like a Docker container. In this configure console, you can configure the container. So it's like a docker-compose.yml.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Select "Task Definitions" at the ECS console&lt;/li&gt;
&lt;li&gt;Select "Create new Task Definition"&lt;/li&gt;
&lt;li&gt;Select "Fargate"&lt;/li&gt;
&lt;li&gt;Name task definition&lt;/li&gt;
&lt;li&gt;Select "ecsTaskExecution" for task role&lt;/li&gt;
&lt;li&gt;Select "Linux" for Operating system family&lt;/li&gt;
&lt;li&gt;Select "0.5GB" for Task memory&lt;/li&gt;
&lt;li&gt;Select "0.25vCPU" for Task CPU&lt;/li&gt;
&lt;li&gt;Add container

&lt;ul&gt;
&lt;li&gt;Container name: Insert name&lt;/li&gt;
&lt;li&gt;Image: Copy ECR Image URI including tag&lt;/li&gt;
&lt;li&gt;Port mappings: "3000"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Create&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  3 Create ECS Service
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;ECS Service is the collection of ECS Tasks and it's related to ALB and AutoScaling Group. ECS Service needs ECS Task when created, but it's technically not a subordinate of ECS Task because you can assign ECS Task to ECS Cluster without Service setting.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Configure service&lt;/li&gt;
&lt;li&gt;Select "Cluster" at the ECS console&lt;/li&gt;
&lt;li&gt;Select the cluster you created&lt;/li&gt;
&lt;li&gt;Select the "Service" tab&lt;/li&gt;
&lt;li&gt;Select "Create"&lt;/li&gt;
&lt;li&gt;Launch type: "Fargate"&lt;/li&gt;
&lt;li&gt;Task Definition: Select the task you created&lt;/li&gt;
&lt;li&gt;Service name: Insert name&lt;/li&gt;
&lt;li&gt;Number of tasks: 1&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Next step" and skip other items&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cluster VPC: choose your VPC for ECS (If you created VPC at "1. Create ECS Cluster", use it )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select Subnets as many as you need&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click "Edit" for Security groups&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add Inbound rules： custom TCP / Anywhere / port 3000&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Next step" and skip other items&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set Auto Scaling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select "Do not adjust the service’s desired count"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Next step"&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⇒ Check all items again, and "Create Service"&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Confirm ECS Fargate running
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Select "Cluster" at the ECS console&lt;/li&gt;
&lt;li&gt;Select the cluster you created&lt;/li&gt;
&lt;li&gt;Select the "Tasks" tab&lt;/li&gt;
&lt;li&gt;Select task running&lt;/li&gt;
&lt;li&gt;Copy public IP&lt;/li&gt;
&lt;li&gt;Access to public IP with &lt;code&gt;:3000&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Good job.&lt;br&gt;
Please make sure you deleted the cluster.&lt;br&gt;
It's better to delete any resources in AWS if you don't need to operate it for a long time or if you just created it for learning.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ecs</category>
      <category>fargate</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
