<?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: Pedro Pablo Camellon</title>
    <description>The latest articles on DEV Community by Pedro Pablo Camellon (@pedropcamellon).</description>
    <link>https://dev.to/pedropcamellon</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%2F695863%2F44a5104a-23e4-4976-b894-b02b4acbd432.JPG</url>
      <title>DEV Community: Pedro Pablo Camellon</title>
      <link>https://dev.to/pedropcamellon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pedropcamellon"/>
    <language>en</language>
    <item>
      <title>Migrating My Portfolio to Jekyll: Why and How</title>
      <dc:creator>Pedro Pablo Camellon</dc:creator>
      <pubDate>Thu, 16 Apr 2026 19:33:06 +0000</pubDate>
      <link>https://dev.to/pedropcamellon/migrating-my-portfolio-to-jekyll-why-and-how-25k2</link>
      <guid>https://dev.to/pedropcamellon/migrating-my-portfolio-to-jekyll-why-and-how-25k2</guid>
      <description>&lt;p&gt;My original workflow was simple by design. I'd write in Notion, leverage Notion AI for faster edits, publish the page, and embed a link to it from my site. The blog itself was just HTML, CSS, and JavaScript—intentionally minimal. This kept the code clean and gave me more time to write.&lt;/p&gt;

&lt;p&gt;But over time, I realized I was too dependent on Notion. My content lived in their database. Every post was a published Notion page that I linked to. If Notion went down, my blog was broken links. I had no version control over my content. No history of edits. No way to track how my writing evolved.&lt;/p&gt;

&lt;p&gt;I wanted my content in Git, tracked natively alongside my code. Markdown felt like the obvious choice—simple, portable, perfect for technical writing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Jekyll?
&lt;/h2&gt;

&lt;p&gt;I was already using GitHub Pages for hosting. Jekyll has native, out-of-the-box support there. No configuration. No build pipelines. Just push markdown files and it works. That alone was compelling.&lt;/p&gt;

&lt;p&gt;But the real reason? Jekyll is mature. It's been around since 2008. The ecosystem is stable. The documentation is thorough. I didn't want to spend time fighting a new framework or debugging alpha-stage tooling. I wanted to write.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Markdown as source of truth.&lt;/strong&gt; My content lives in Git now. Every post is a markdown file. Every edit is a commit. I can track how my writing evolved, roll back mistakes, and branch for experiments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Native GitHub Pages integration.&lt;/strong&gt; Push to &lt;code&gt;main&lt;/code&gt; and it's live. GitHub handles the build. No CI/CD config needed. No deployment scripts. It just works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static site generators made sense.&lt;/strong&gt; My blog was already static HTML. Static site generators are perfect for this—fast, simple, and well-suited for content-focused sites.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automated everything.&lt;/strong&gt; Posts sort themselves by date. Tags display automatically. Excerpts appear in blog cards but not in articles. The "NEW" badge shows up based on a simple frontmatter flag.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep it minimal.&lt;/strong&gt; I didn't want framework hacks. No endless plugin dependencies. No complex build setups. Jekyll lets me focus on writing, not on tooling. The site does one thing well: display markdown content.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Migration Journey
&lt;/h2&gt;

&lt;p&gt;The migration happened in phases over a weekend. My old site was intentionally simple—HTML, CSS, JavaScript. Blog posts were just links to published Notion pages. Clean, but not sustainable.&lt;/p&gt;

&lt;p&gt;I started by setting up Jekyll's basic structure—a &lt;code&gt;_config.yml&lt;/code&gt; file, a simple Gemfile, and the essential &lt;code&gt;_layouts/default.html&lt;/code&gt; template. That template became the heart of the site, handling navigation, analytics, and the footer for every page.&lt;/p&gt;

&lt;p&gt;Next came the CSS. I kept it minimal. Two focused files: &lt;code&gt;main.css&lt;/code&gt; for base styles (typography, navigation, code blocks, tables) and &lt;code&gt;pages.css&lt;/code&gt; for components (hero section, blog cards, responsive design). No frameworks. No bloat. Just what I needed.&lt;/p&gt;

&lt;p&gt;The blog list transformation was where Jekyll really shined. What used to be manual HTML became a simple Liquid template that filters, sorts, and displays posts automatically. Jekyll handles the heavy lifting—I just write markdown.&lt;/p&gt;

&lt;p&gt;Migrating 20+ existing posts from Notion could have been tedious, so I automated it with a PowerShell script. The script extracts excerpts, adjusts heading levels, renames images with descriptive prefixes, and generates consistent frontmatter. What would have taken days took an afternoon. That was the last time I pulled content from Notion.&lt;/p&gt;

&lt;p&gt;Now, I still brainstorm in Notion—it's great for messy thinking. But when it's time to write, I open VS Code, create a markdown file, and the content lives in Git from day one.&lt;/p&gt;

&lt;p&gt;Even the projects page got simpler. Instead of maintaining an HTML table with inline styles, I converted it to markdown with badge-style GitHub and blog links. Jekyll's built-in table rendering handled the rest.&lt;/p&gt;

&lt;p&gt;You can see all the code in the &lt;a href="https://github.com/pedropcamellon/pedropcamellon.github.io" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;—it's cleaner than any tutorial could show.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Frontmatter Philosophy
&lt;/h2&gt;

&lt;p&gt;Every blog post now starts with consistent frontmatter that tells Jekyll everything it needs to know:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Article&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Title"&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-04-07&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;web-dev"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jekyll"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;thumbnail.webp"&lt;/span&gt;
&lt;span class="na"&gt;excerpt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;One-sentence&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;summary&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;blog&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;cards"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;date&lt;/code&gt; field controls sorting. The &lt;code&gt;is_new&lt;/code&gt; flag shows the "NEW" badge (I remove it after a few weeks). The &lt;code&gt;excerpt&lt;/code&gt; appears only in blog cards, never in the article itself. It's metadata-driven content management at its simplest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local Development: Docker Saves the Day
&lt;/h2&gt;

&lt;p&gt;Setting up Ruby environments can be painful. Version conflicts, gem dependencies, platform-specific issues—it's a rabbit hole. Docker solved all of it.&lt;/p&gt;

&lt;p&gt;I created a simple &lt;code&gt;docker-compose.yml&lt;/code&gt; that spins up Jekyll 4.2.2 with live reload. No Ruby installation needed. No version conflicts. Just &lt;code&gt;docker compose up&lt;/code&gt; and start writing. The development server runs at &lt;code&gt;localhost:4000&lt;/code&gt; with instant preview of changes.&lt;/p&gt;

&lt;p&gt;The only hiccup? SSL certificate errors when Docker tried to fetch gems from &lt;code&gt;https://rubygems.org&lt;/code&gt;. The fix was simple: change the Gemfile source to &lt;code&gt;http://rubygems.org&lt;/code&gt;. Not ideal for production, but perfectly fine for local development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment: Git Push and Forget
&lt;/h2&gt;

&lt;p&gt;The deployment workflow is delightfully simple. Edit files locally. Commit changes. Push to the &lt;code&gt;main&lt;/code&gt; branch. GitHub Pages automatically builds and deploys the site. I don't even commit the &lt;code&gt;_site/&lt;/code&gt; build directory—GitHub handles it server-side.&lt;/p&gt;

&lt;p&gt;For preview environments, I set up a GitHub Actions workflow that deploys the &lt;code&gt;dev&lt;/code&gt; branch to a separate URL. It's useful for testing major changes before they go live.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Convenience can become dependency.&lt;/strong&gt; Embedding Notion links was easy. Too easy. I traded control for convenience and didn't realize it until I wanted my content in Git.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maturity matters.&lt;/strong&gt; Jekyll isn't the newest or flashiest static site generator. But it's battle-tested. The documentation is solid. The ecosystem is stable. That's worth more than cutting-edge features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep it minimal to focus on writing.&lt;/strong&gt; I could have added a dozen frameworks and plugins. But every dependency is a potential distraction. Minimal tooling means more time writing, less time debugging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notion for brainstorming, Git for publishing.&lt;/strong&gt; Notion is still valuable for messy thinking. But polished content belongs in version control. Separate the tools, keep both useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker is worth the setup.&lt;/strong&gt; I avoided days of Ruby environment troubleshooting by starting with Docker. The consistency across machines is invaluable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automation compounds.&lt;/strong&gt; That PowerShell import script saved hours on the initial migration. But more importantly, it'll save hours every time I import new posts. Time spent on automation is time invested.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontmatter is powerful.&lt;/strong&gt; Separating metadata from content keeps everything clean. Tags, excerpts, dates, badges—all controlled through simple YAML fields.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static site generators are perfect for blogs.&lt;/strong&gt; My site was already static HTML. Jekyll just formalized it. Fast, simple, and perfectly suited for content-focused sites.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Results
&lt;/h2&gt;

&lt;p&gt;Before: Write in Notion → Publish Notion page → Embed link in site → Hope Notion stays up.&lt;br&gt;&lt;br&gt;
Now: Write markdown → Commit to Git → Push. Done.&lt;/p&gt;

&lt;p&gt;My content is version controlled. Every post has edit history. The site is faster (no external dependencies on Notion). And I'm not locked into one platform anymore.&lt;/p&gt;

&lt;p&gt;More importantly, I'm writing more. The friction of "where does this content live?" is gone. Markdown files in Git feel right. The mental overhead vanished.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;I'm keeping a list of potential enhancements—search functionality, pagination, dark mode, WebP image optimization as a part of the GitHub Action, reading time estimates. But I'm not rushing. The site works. It's minimal by design. Every feature I don't add is one less thing to maintain.&lt;/p&gt;

&lt;p&gt;So far, keeping it minimal has been the right choice. I'm focused on writing, not on framework hacks. That was the whole point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/pedropcamellon/pedropcamellon.github.io" rel="noopener noreferrer"&gt;pedropcamellon.github.io&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://jekyllrb.com/docs/" rel="noopener noreferrer"&gt;Jekyll Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/about-github-pages-and-jekyll" rel="noopener noreferrer"&gt;GitHub Pages + Jekyll Guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://shopify.github.io/liquid/" rel="noopener noreferrer"&gt;Liquid Template Language&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/testing-your-github-pages-site-locally-with-jekyll" rel="noopener noreferrer"&gt;Testing Your GitHub Pages Site Locally with Jekyll&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;- &lt;br&gt;
Originally published here: &lt;a href="https://pedropcamellon.github.io/blog/2026-04-07-migrating-portfolio-to-jekyll/2026-04-07-migrating-portfolio-to-jekyll.html" rel="noopener noreferrer"&gt;https://pedropcamellon.github.io/blog/2026-04-07-migrating-portfolio-to-jekyll/2026-04-07-migrating-portfolio-to-jekyll.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>git</category>
      <category>webdev</category>
      <category>website</category>
    </item>
    <item>
      <title>Orchestration vs Choreography: Two Ways to Build Clinical Speech-to-Text</title>
      <dc:creator>Pedro Pablo Camellon</dc:creator>
      <pubDate>Thu, 16 Apr 2026 19:30:49 +0000</pubDate>
      <link>https://dev.to/pedropcamellon/orchestration-vs-choreography-two-ways-to-build-clinical-speech-to-text-2c7i</link>
      <guid>https://dev.to/pedropcamellon/orchestration-vs-choreography-two-ways-to-build-clinical-speech-to-text-2c7i</guid>
      <description>&lt;p&gt;I built clinical transcription twice — once with event-driven choreography on AWS, once with workflow orchestration in &lt;a href="https://github.com/FoliumAI/folium" rel="noopener noreferrer"&gt;Folium EHR&lt;/a&gt;. I wrote about the first approach in the &lt;a href="https://pedropcamellon.github.io/blog/2024-04-27-medical-calls-analysis-in-aws-part-1-getting-started/2024-04-27-medical-calls-analysis-in-aws-part-1-getting-started.html" rel="noopener noreferrer"&gt;Medical Calls Analysis series&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The core insight: &lt;strong&gt;choreography and orchestration are not the same thing.&lt;/strong&gt; I used to mentally lump them together as "async" until I built both and felt the tradeoffs up close. The difference matters a lot more when you're handling clinical data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Patterns for Async Work
&lt;/h2&gt;

&lt;p&gt;Before getting into the specifics, it's worth naming the two patterns clearly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choreography&lt;/strong&gt; (event-driven): each service reacts to events independently. No central coordinator. S3 emits an event, Lambda picks it up, writes to S3, another Lambda picks that up. Each service knows its own job and nothing else. The "workflow" is an emergent property of events flowing between services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Orchestration&lt;/strong&gt; (workflow-driven): a central coordinator defines the steps, owns the state, and controls the sequence. Each step is an explicit function call. The workflow is the code — one file, readable, testable, versionable.&lt;/p&gt;

&lt;p&gt;Both are valid. They optimize for different things.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Choreography Approach
&lt;/h2&gt;

&lt;p&gt;The AWS pattern for clinical transcription is well-established. S3 event → Lambda → Transcribe → S3 → Lambda → Bedrock → S3. Fully managed. Scales to zero. Costs almost nothing at low volume. I built a version of this in the &lt;a href="https://pedropcamellon.github.io/blog/2024-04-27-medical-calls-analysis-in-aws-part-1-getting-started/2024-04-27-medical-calls-analysis-in-aws-part-1-getting-started.html" rel="noopener noreferrer"&gt;Medical Calls Analysis series&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Choreography is a solid default for a lot of systems.&lt;/p&gt;

&lt;p&gt;But think about what happens when a Lambda times out mid-pipeline. The message hits the DLQ. No alarm fires. Nobody notices for hours. A clinician's notes from that morning are just... gone. No error surface, no visible status, no obvious place to even start looking.&lt;/p&gt;

&lt;p&gt;To debug it, you correlate CloudWatch logs across three Lambda functions, check the SQS DLQ, inspect S3 prefixes, and piece together what happened from timestamps.&lt;/p&gt;

&lt;p&gt;That's the fundamental tradeoff of choreography: &lt;strong&gt;there's no centralized state.&lt;/strong&gt; Each service knows its own slice. Nobody knows the full picture of a single job. To answer "where is this transcription right now?" you have to ask five different systems and hope the correlation IDs line up.&lt;/p&gt;

&lt;p&gt;Choreography gives you decoupling and independence. It takes away visibility and coordinated failure handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tradeoffs
&lt;/h2&gt;

&lt;p&gt;I don’t think orchestration is “better” in a vacuum. It comes with real costs and tradeoffs, and in a lot of systems choreography is the right call.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where choreography tends to win
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure:&lt;/strong&gt; Fully managed primitives (S3, Lambda, SQS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost at low volume:&lt;/strong&gt; Nearly free (pay-per-invoke)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Getting started:&lt;/strong&gt; Wire an event and ship it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coupling:&lt;/strong&gt; Services are decoupled by default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failure blast radius:&lt;/strong&gt; Distributed. One function timing out does not pause the whole system&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Where orchestration tends to win
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Failure visibility:&lt;/strong&gt; Built-in workflow history and status&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retry control:&lt;/strong&gt; Per-step retries with backoff and error classes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging:&lt;/strong&gt; You can inspect one workflow run instead of correlating logs across services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State:&lt;/strong&gt; Centralized state for a single job ("where is this transcription right now?")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One tradeoff that’s easy to underestimate: with orchestration, the coordinator is load-bearing infrastructure. If it goes down, workflows pause until it comes back. With choreography, failures are more distributed by design.&lt;/p&gt;

&lt;p&gt;Orchestration engines also enforce constraints that can trip you up at first. In Temporal, workflow code must be deterministic (no random numbers, no direct I/O, no &lt;code&gt;datetime.now()&lt;/code&gt;). Side effects go in activities, coordination goes in workflows.&lt;/p&gt;

&lt;p&gt;A small but important implication: if the workflow fails during step 2, the engine retries step 2. Steps 1 and 3 do not re-run. That is deterministic replay in practice.&lt;/p&gt;

&lt;p&gt;This annoyed me at first. Then I realized it forces a clean separation I'd want anyway: &lt;strong&gt;coordination logic vs. real work.&lt;/strong&gt; It's just good architecture with the engine enforcing it.&lt;/p&gt;

&lt;p&gt;But if your team has never worked with orchestration engines, budget real ramp-up time. The mental model is genuinely different from event-driven.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Healthcare Tips the Scale Toward Orchestration
&lt;/h2&gt;

&lt;p&gt;In most domains, choreography's tradeoffs are acceptable. A lost analytics event or a delayed notification isn't catastrophic.&lt;/p&gt;

&lt;p&gt;Healthcare is different.&lt;/p&gt;

&lt;p&gt;A lost transcription is a lost patient encounter. A Lambda timeout mid-pipeline can mean the message hits the DLQ, no alarm fires, and nobody finds out until a clinician reports missing notes. That's not a bug report. That's a compliance incident.&lt;/p&gt;

&lt;p&gt;Orchestration gives you an audit trail by default. Every event logged, every state transition queryable. HIPAA wants to know where PHI flows and who touched it? It's in the workflow history. In a choreographed setup, building an equivalent audit trail is a separate project — one that's easy to deprioritize until you need it.&lt;/p&gt;

&lt;p&gt;The "async trap" is real: choreography gives you non-blocking execution but not durability. A crashed function can lose its in-flight job. A crashed orchestration worker is just a pause. The workflow picks up on the next available worker.&lt;/p&gt;

&lt;p&gt;In healthcare, durability isn't a nice-to-have. It's the whole point.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;Polling for transcription status is the current approach in Folium. WebSocket push would cut latency and reduce server load. That's the natural next step.&lt;/p&gt;

&lt;p&gt;I'd also formalize workflow IDs around patient encounter IDs from day one. Orchestration workflows are naturally idempotent when keyed to a business ID. Start the same workflow ID twice and the engine just returns the existing run.&lt;/p&gt;

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

&lt;p&gt;For multi-step AI workflows where failures matter, I’ve found orchestration to be the better fit. The visibility and durability are hard to replicate in a choreographed system, and in healthcare those properties matter a lot.&lt;/p&gt;

&lt;p&gt;For a simple event trigger (thumbnail resize, log processor, webhook relay), choreography is usually simpler, cheaper, and perfectly fine when losing one event isn’t the end of the world.&lt;/p&gt;

&lt;p&gt;The mistake is treating these as the same category. "Async" is not one thing. Choreography and orchestration solve different problems. I learned that by building the same system twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Temporal docs: &lt;a href="https://docs.temporal.io/" rel="noopener noreferrer"&gt;https://docs.temporal.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Temporal Concepts (workflows, activities, determinism): &lt;a href="https://docs.temporal.io/concepts" rel="noopener noreferrer"&gt;https://docs.temporal.io/concepts&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AWS Serverless Event-Driven Architecture patterns: &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/serverless-architectures-lambda/serverless-architectures-lambda.pdf" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/whitepapers/latest/serverless-architectures-lambda/serverless-architectures-lambda.pdf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AWS SQS DLQ docs: &lt;a href="https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;-- &lt;br&gt;
Originally published at &lt;a href="https://pedropcamellon.github.io/blog/2026-04-16-async-clinical-transcription-temporal-vs-event-driven/2026-04-16-async-clinical-transcription-temporal-vs-event-driven.html" rel="noopener noreferrer"&gt;pedropcamellon.github.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>eventdriven</category>
      <category>architecture</category>
      <category>aws</category>
    </item>
  </channel>
</rss>
