<?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: Sospeter Mong'are</title>
    <description>The latest articles on DEV Community by Sospeter Mong'are (@msnmongare).</description>
    <link>https://dev.to/msnmongare</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%2F117091%2F89122cee-2645-481e-b979-f96819dc9d1b.jpeg</url>
      <title>DEV Community: Sospeter Mong'are</title>
      <link>https://dev.to/msnmongare</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/msnmongare"/>
    <language>en</language>
    <item>
      <title>Premature Optimization in Software Engineering: When Trying to Be Clever Becomes the Problem</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Fri, 23 Oct 2026 09:22:36 +0000</pubDate>
      <link>https://dev.to/msnmongare/premature-optimization-in-software-engineering-when-trying-to-be-clever-becomes-the-problem-i1d</link>
      <guid>https://dev.to/msnmongare/premature-optimization-in-software-engineering-when-trying-to-be-clever-becomes-the-problem-i1d</guid>
      <description>&lt;p&gt;There is a mistake developers make that often looks like good engineering.&lt;/p&gt;

&lt;p&gt;You start building a feature, and before it even works, you are already thinking about caching, database indexes, microservices, asynchronous processing, memory allocation, and how the system will handle a million users.&lt;/p&gt;

&lt;p&gt;You haven't even shipped the first version.&lt;/p&gt;

&lt;p&gt;But somehow, you're already optimizing for a million users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Welcome to premature optimization.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Premature Optimization?
&lt;/h2&gt;

&lt;p&gt;Premature optimization is the practice of making code faster or more resource-efficient before you have evidence that the optimization is necessary.&lt;/p&gt;

&lt;p&gt;It happens when developers optimize based on assumptions rather than measurements.&lt;/p&gt;

&lt;p&gt;For example, you are building an API that retrieves customer records. Instead of implementing a straightforward database query, you immediately introduce Redis caching, a complex caching invalidation strategy, background workers, and multiple layers of abstraction.&lt;/p&gt;

&lt;p&gt;All this effort goes into solving a performance problem you haven't established exists.&lt;/p&gt;

&lt;p&gt;Perhaps the query takes 15 milliseconds. Perhaps the application has only 50 users. Perhaps the real bottleneck is an external API that takes two seconds to respond.&lt;/p&gt;

&lt;p&gt;You have optimized the wrong thing.&lt;/p&gt;

&lt;p&gt;And the worst part? You now have more code to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Origin of "Premature Optimization Is the Root of All Evil"
&lt;/h2&gt;

&lt;p&gt;The phrase is commonly associated with Donald Knuth, one of the most influential computer scientists.&lt;/p&gt;

&lt;p&gt;In his 1974 paper, &lt;em&gt;Structured Programming with Go To Statements&lt;/em&gt;, Knuth wrote:&lt;/p&gt;

&lt;p&gt;"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%."&lt;/p&gt;

&lt;p&gt;Notice something important about this quote.&lt;/p&gt;

&lt;p&gt;Knuth wasn't arguing that performance doesn't matter. He was arguing that developers should distinguish between meaningful optimization and unnecessary attempts to make code more efficient.&lt;/p&gt;

&lt;p&gt;There is a critical 3% where performance decisions matter enormously. The challenge is identifying that 3% instead of treating every line of code as a performance emergency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Premature Optimization Is Dangerous
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. You waste time solving imaginary problems
&lt;/h3&gt;

&lt;p&gt;Engineering time is limited. Every hour spent optimizing code that doesn't need optimization is an hour you could have spent improving functionality, fixing bugs, strengthening security, or delivering value to users.&lt;/p&gt;

&lt;p&gt;A developer who spends two days optimizing an operation that executes once per day might achieve an impressive benchmark and almost zero business impact.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. You introduce unnecessary complexity
&lt;/h3&gt;

&lt;p&gt;Simple code is often easier to understand, test, debug, and maintain.&lt;/p&gt;

&lt;p&gt;Premature optimization can introduce custom caching mechanisms, complicated concurrency patterns, unnecessary abstractions, and clever algorithms that future developers will struggle to understand.&lt;/p&gt;

&lt;p&gt;The code might become marginally faster, but significantly harder to maintain.&lt;/p&gt;

&lt;p&gt;And remember, software doesn't end when you write it. Someone has to operate it, debug it, extend it, and eventually replace it.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. You optimize the wrong bottleneck
&lt;/h3&gt;

&lt;p&gt;This is perhaps the most expensive mistake.&lt;/p&gt;

&lt;p&gt;Imagine your API takes three seconds to return a response. You assume your Python code is slow, so you spend hours optimizing loops and rewriting functions.&lt;/p&gt;

&lt;p&gt;After profiling the application, you discover that 2.7 seconds are spent waiting for a poorly indexed database query.&lt;/p&gt;

&lt;p&gt;Your Python optimization was never going to make a meaningful difference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without measurement, optimization is often just educated guessing.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. You create technical debt before delivering value
&lt;/h3&gt;

&lt;p&gt;Every additional component introduces decisions and potential failure points.&lt;/p&gt;

&lt;p&gt;Caching requires invalidation strategies. Background jobs require retry mechanisms. Distributed services require observability and communication management.&lt;/p&gt;

&lt;p&gt;These are valuable engineering tools when the problem warrants them. Introduced unnecessarily, they become liabilities.&lt;/p&gt;

&lt;p&gt;The goal is not to avoid sophisticated architecture. The goal is to earn that complexity by solving a real problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Example: Building a Payment API
&lt;/h2&gt;

&lt;p&gt;Suppose you are developing an API that processes mobile money payments.&lt;/p&gt;

&lt;p&gt;Your first implementation validates a request, calls the payment provider, stores the transaction, and returns a response.&lt;/p&gt;

&lt;p&gt;It works correctly, but you want to make it production-ready.&lt;/p&gt;

&lt;p&gt;A premature optimizer might immediately introduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redis caching across transaction-related endpoints.&lt;/li&gt;
&lt;li&gt;Multiple microservices for payment processing.&lt;/li&gt;
&lt;li&gt;A distributed message broker before there is a demonstrated need.&lt;/li&gt;
&lt;li&gt;Complex concurrency mechanisms to handle hypothetical traffic.&lt;/li&gt;
&lt;li&gt;Custom database optimizations without examining query performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A more disciplined engineer asks different questions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are payment requests processing correctly?&lt;/li&gt;
&lt;li&gt;Are duplicate callbacks causing duplicate transactions?&lt;/li&gt;
&lt;li&gt;Are database queries slow under realistic traffic?&lt;/li&gt;
&lt;li&gt;What happens when the payment provider times out?&lt;/li&gt;
&lt;li&gt;Can the system handle the expected transaction volume?&lt;/li&gt;
&lt;li&gt;What do the logs, metrics, and traces reveal?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions matter because payment systems have correctness, reliability, and security requirements that cannot be sacrificed for speed.&lt;/p&gt;

&lt;p&gt;For example, implementing idempotency to prevent duplicate payment processing is not pointless premature optimization. It is a correctness and reliability requirement.&lt;/p&gt;

&lt;p&gt;Likewise, adding indexes to address a measured slow query is a justified optimization.&lt;/p&gt;

&lt;p&gt;The distinction is simple: &lt;strong&gt;build for known requirements, measure actual behavior, and optimize based on evidence.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So, When Should You Optimize?
&lt;/h2&gt;

&lt;p&gt;A practical approach is to follow four steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Make it work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implement the feature using a clear, maintainable design. Focus on correctness, readability, security, and the actual business requirement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Establish a baseline.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Measure response times, throughput, memory consumption, database query duration, and error rates where relevant.&lt;/p&gt;

&lt;p&gt;You cannot confidently claim an improvement if you don't know where you started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Profile the application.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use tools appropriate to your stack, such as Python profilers, database query plans, application performance monitoring, distributed tracing, and load-testing tools.&lt;/p&gt;

&lt;p&gt;Find out where the time and resources are actually going.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Optimize, then measure again.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Address the bottleneck with the greatest impact. Rerun your tests and compare the results against the baseline.&lt;/p&gt;

&lt;p&gt;If the optimization adds significant complexity for negligible improvement, reconsider whether it is worth keeping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does This Mean We Should Ignore Scalability?
&lt;/h2&gt;

&lt;p&gt;Absolutely not.&lt;/p&gt;

&lt;p&gt;This is where the conversation often goes wrong.&lt;/p&gt;

&lt;p&gt;Good engineering requires anticipating future needs. Security, data integrity, accessibility, and architectural constraints should not be ignored until something breaks.&lt;/p&gt;

&lt;p&gt;If you know your application must process thousands of transactions per second, you should design and test for that requirement from the beginning.&lt;/p&gt;

&lt;p&gt;If you are building a multi-tenant SaaS platform, tenant isolation and authorization must be part of the architecture from day one.&lt;/p&gt;

&lt;p&gt;If you are developing an AI application, you should consider token costs, latency, rate limits, and model availability early because they directly affect the product.&lt;/p&gt;

&lt;p&gt;But there is a difference between &lt;strong&gt;designing for known constraints and optimizing for imaginary ones.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You should make sound architectural decisions early without unnecessarily implementing every possible performance improvement upfront.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lesson for Software Engineers in the AI Era
&lt;/h2&gt;

&lt;p&gt;This principle is even more relevant today.&lt;/p&gt;

&lt;p&gt;AI coding assistants can generate caching layers, database abstractions, queues, complex design patterns, and entire service architectures in minutes.&lt;/p&gt;

&lt;p&gt;But the fact that an AI tool can generate a solution quickly doesn't mean that solution is necessary.&lt;/p&gt;

&lt;p&gt;A developer who asks an AI assistant to optimize code without profiling it may end up with more complexity, new bugs, and little or no measurable improvement.&lt;/p&gt;

&lt;p&gt;The responsibility of the engineer is to understand the problem, evaluate the proposed solution, verify the results, and determine whether the additional complexity is justified.&lt;/p&gt;

&lt;p&gt;AI can help write the code. Engineering judgment determines whether the code should exist in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Premature optimization is not about writing simple code forever. It is about knowing when simplicity is sufficient and when complexity becomes necessary.&lt;/p&gt;

&lt;p&gt;Don't spend days optimizing a feature before understanding its performance characteristics. Don't introduce distributed systems because they sound impressive. Don't confuse architectural sophistication with engineering excellence.&lt;/p&gt;

&lt;p&gt;Build the right thing. Measure how it behaves. Identify the bottleneck. Optimize where it matters.&lt;/p&gt;

&lt;p&gt;And always remember: &lt;strong&gt;the fastest code to maintain is often the code you never needed to write.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>productivity</category>
      <category>python</category>
    </item>
    <item>
      <title>PHP2Shell: Two Critical PHP Remote Code Execution Flaws (CVE-2026-109618 and CVE-2026-109619) and How to Patch Them</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Thu, 22 Oct 2026 08:08:58 +0000</pubDate>
      <link>https://dev.to/msnmongare/php2shell-two-critical-php-remote-code-execution-flaws-cve-2026-109618-and-cve-2026-109619-and-3j9k</link>
      <guid>https://dev.to/msnmongare/php2shell-two-critical-php-remote-code-execution-flaws-cve-2026-109618-and-cve-2026-109619-and-3j9k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;On October 21, 2026, the PHP project shipped emergency security releases for two critical vulnerabilities nicknamed &lt;strong&gt;PHP2Shell&lt;/strong&gt;. They let an unauthenticated attacker run code on a server through an ordinary HTTP request, and they live in the PHP engine itself, so a perfectly written application can still be exposed. Because PHP powers WordPress, Magento, Drupal, countless control panels and most shared hosting, the reach is enormous.&lt;/p&gt;

&lt;p&gt;The confusing part is the patching. Ubuntu and other distributions fix PHP without changing the version number, so a server reporting an old version such as 8.3.6 might be vulnerable or might be fully patched. Shared hosting customers and WordPress owners also can't simply "run an update". This article explains what the flaws are, which versions are affected, which are fixed, and exactly what to do whether you run your own Ubuntu server, a cPanel server, shared hosting, or a WordPress site.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened
&lt;/h2&gt;

&lt;p&gt;On October 21, 2026, the PHP team released emergency security updates for PHP2Shell, two critical vulnerabilities (CVE-2026-109618 and CVE-2026-109619) that could let attackers execute code remotely on web servers without logging in. The PHP security team rated each 9.2 on CVSS v4.0, and security firm watchTowr rated it a full 10.0.&lt;/p&gt;

&lt;p&gt;The flaws are in the PHP engine itself, not in any one application. Magento, Shopware and WooCommerce stores are exposed even when their own code is clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two vulnerabilities
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2026-109618, "RCE via OOM corruption."&lt;/strong&gt; Out-of-memory handling can interrupt PHP while internal request data is only partially initialized, and request cleanup may then treat the invalid data as valid. JFrog's analysis says it can also cause Heartbleed-style memory disclosure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2026-109619, "RCE via stale global state."&lt;/strong&gt; A PHP worker can reuse stale state from a previous request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Researchers describe the internals differently. Several tie both bugs to PHP's session upload-progress feature, which is why disabling that feature is the main stopgap (see below).&lt;/p&gt;

&lt;h2&gt;
  
  
  Affected versions
&lt;/h2&gt;

&lt;p&gt;Versions as early as PHP 5.4 through PHP 8 are affected, so the vulnerable code is about 14 years old. Every PHP installation that serves web requests is affected, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixed versions
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Branch&lt;/th&gt;
&lt;th&gt;Vulnerable&lt;/th&gt;
&lt;th&gt;Fixed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8.5&lt;/td&gt;
&lt;td&gt;before 8.5.12&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.5.12&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8.4&lt;/td&gt;
&lt;td&gt;before 8.4.27&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.4.27&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8.3&lt;/td&gt;
&lt;td&gt;before 8.3.36&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.3.36&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8.2&lt;/td&gt;
&lt;td&gt;before 8.2.35&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.2.35&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8.1 and earlier&lt;/td&gt;
&lt;td&gt;End of life&lt;/td&gt;
&lt;td&gt;No standard release&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you run an end-of-life branch, moving to a supported branch is the real fix. PHP 8.2 also reaches end of life on 31 December 2026, so don't treat 8.2 as a long-term home.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is it being exploited?
&lt;/h2&gt;

&lt;p&gt;Reports differ. Amazon Threat Intelligence recorded an exploitation attempt on October 17, four days before public disclosure, and Cloudflare has also reported attack traffic, including attempts to evade its protections. However, as of October 21, PHP had not reported in-the-wild exploitation, and CISA had not added either CVE to its catalog. Treat it as actively targeted either way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do you really need to upgrade?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Yes, you need to upgrade, but not to 8.3.36 if you installed PHP from Ubuntu's own repositories.&lt;/strong&gt; Staying on the Ubuntu package is fine and is the recommended route. Ubuntu backports fixes without changing the version number, so you need the right build of 8.3.6, not a new PHP version.&lt;/p&gt;

&lt;p&gt;For Ubuntu 24.04 (Noble), the fixed package is &lt;strong&gt;8.3.6-0ubuntu0.24.04.13&lt;/strong&gt;. That build is fixed even though it says 8.3.6. Anything older, such as &lt;code&gt;.9&lt;/code&gt;, &lt;code&gt;.10&lt;/code&gt; or &lt;code&gt;.11&lt;/code&gt;, is still vulnerable, even though &lt;code&gt;php -v&lt;/code&gt; looks identical. Ubuntu's advisories are USN-8948-1 and USN-8948-2.&lt;/p&gt;

&lt;p&gt;The rule of thumb: the version string alone doesn't tell you whether you're patched. If PHP came from your distribution, check the package build and changelog. If it came from upstream or a third-party repository (such as Ondřej Surý's PPA), you need 8.3.36 or later.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to patch your own server
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ubuntu and Debian (distribution packages)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# What's installed?&lt;/span&gt;
dpkg &lt;span class="nt"&gt;-l&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'^ii\s+php8.3'&lt;/span&gt;

&lt;span class="c"&gt;# Upgrade&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade        &lt;span class="c"&gt;# or: sudo apt install --only-upgrade 'php8.3*' 'libapache2-mod-php8.3'&lt;/span&gt;

&lt;span class="c"&gt;# Confirm: on Ubuntu 24.04 the version should end in .13 or higher&lt;/span&gt;
dpkg &lt;span class="nt"&gt;-l&lt;/span&gt; php8.3-cli | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
apt changelog php8.3-cli | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; CVE-2026

&lt;span class="c"&gt;# Restart so running workers pick up the fix&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart php8.3-fpm     &lt;span class="c"&gt;# PHP-FPM&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart apache2        &lt;span class="c"&gt;# mod_php&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the command is &lt;code&gt;apt changelog&lt;/code&gt;, not &lt;code&gt;apt-changelog&lt;/code&gt;. Restarting is essential: updated packages do not affect already-running workers. If you added a third-party PPA, check which repository supplies the package with &lt;code&gt;apt-cache policy php8.3-cli&lt;/code&gt; and make sure you reach 8.3.36 or later.&lt;/p&gt;

&lt;p&gt;On Debian, check the Debian security tracker for the fixed package version of your release, as I could not verify it at the time of writing.&lt;/p&gt;

&lt;h3&gt;
  
  
  RHEL, Rocky and AlmaLinux
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf upgrade &lt;span class="s1"&gt;'php*'&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart php-fpm     &lt;span class="c"&gt;# or httpd, depending on your setup&lt;/span&gt;
rpm &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;--changelog&lt;/span&gt; php-fpm | &lt;span class="nb"&gt;grep &lt;/span&gt;CVE-2026
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  cPanel/WHM servers (root access)
&lt;/h3&gt;

&lt;p&gt;cPanel ships its own PHP builds (ea-php), separate from the operating system's PHP. Fixed builds were backported at the same version for older branches: ea-php74 7.4.33-19, ea-php80 8.0.30-12 and ea-php81 8.1.34-5. Update with &lt;code&gt;/scripts/upcp&lt;/code&gt;, or &lt;code&gt;dnf upgrade 'ea-php*'&lt;/code&gt; (&lt;code&gt;yum&lt;/code&gt; on EL7), then restart Apache or PHP-FPM. The fixed build numbers for the newer ea-php branches (8.2 and up) were not confirmed, so check cPanel's EasyApache 4 changelog. If you resell hosting, check each account's PHP version in MultiPHP Manager, because accounts pinned to different versions can be patched at different times.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared hosting (no root access)
&lt;/h2&gt;

&lt;p&gt;You can't patch PHP yourself on shared hosting. Your host has to. Here is what you can do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check your PHP version in cPanel under &lt;strong&gt;MultiPHP Manager&lt;/strong&gt;, or put &lt;code&gt;&amp;lt;?php phpinfo();&lt;/code&gt; in a temporary file and delete it right after. Remember a backported build can still show an old version number.&lt;/li&gt;
&lt;li&gt;Ask your host in writing whether PHP2Shell (CVE-2026-109618 and CVE-2026-109619) is patched, and when.&lt;/li&gt;
&lt;li&gt;Apply the stopgap. In cPanel's &lt;strong&gt;MultiPHP INI Editor&lt;/strong&gt;, or in a &lt;code&gt;.user.ini&lt;/code&gt; file in your site root, set &lt;code&gt;session.upload_progress.enabled = Off&lt;/code&gt;. Some hosts lock these settings, so confirm it took effect. Updating is still the only complete fix.&lt;/li&gt;
&lt;li&gt;Don't rely on a lower-numbered PHP version as a workaround. Everything from PHP 5.4 up is affected.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  WordPress sites
&lt;/h2&gt;

&lt;p&gt;The vulnerability is in PHP, not in WordPress, so updating WordPress core, themes or plugins does &lt;strong&gt;not&lt;/strong&gt; fix it. Because the flaws are in the PHP engine, sites are exposed even when their own code is clean. Do this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get PHP patched (by your host or on your server), then restart PHP.&lt;/li&gt;
&lt;li&gt;Disable &lt;code&gt;session.upload_progress&lt;/code&gt; in the meantime.&lt;/li&gt;
&lt;li&gt;Put a WAF in front of the site if you can. Cloudflare has reported attack traffic targeting these flaws.&lt;/li&gt;
&lt;li&gt;Look for signs of compromise: unfamiliar PHP files in &lt;code&gt;wp-content/uploads&lt;/code&gt;, new admin users, modified &lt;code&gt;.htaccess&lt;/code&gt;, and unusual file modification dates. Check logs back to at least October 17, since exploitation was recorded four days before disclosure.&lt;/li&gt;
&lt;li&gt;Take a backup before and after patching.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  If you can't patch immediately
&lt;/h2&gt;

&lt;p&gt;Updating is the only complete fix. As a stopgap, disable the session upload-progress feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;session.upload_progress.enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;Off&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Put it in your php.ini or a conf.d file, then restart PHP. Also consider WAF rules and request-size limits at your proxy. After patching, review logs for unusual multipart POST requests and unexpected PHP worker crashes or memory errors, going back to at least October 17.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes to avoid
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Assuming &lt;code&gt;php -v&lt;/code&gt; showing 8.3.6 means you are vulnerable (on Ubuntu it may be patched) or that it means you are safe (it may not be). Check the package build.&lt;/li&gt;
&lt;li&gt;Upgrading the package but not restarting PHP-FPM or Apache.&lt;/li&gt;
&lt;li&gt;Updating WordPress and assuming that closes the hole.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;apt-changelog&lt;/code&gt;, which is not a standard command. Use &lt;code&gt;apt changelog &amp;lt;package&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Staying on an end-of-life PHP branch with no fix available.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;PHP2Shell is serious because it needs no login, sits in PHP itself, and has been probed in the wild since before disclosure. The good news is that fixes are out for every supported branch: 8.5.12, 8.4.27, 8.3.36 and 8.2.35 upstream, and backported builds from Ubuntu (8.3.6-0ubuntu0.24.04.13 on 24.04) and cPanel. If you manage your own server, update, restart PHP and verify the package changelog. If you are on shared hosting, press your provider for a patch date and apply the &lt;code&gt;session.upload_progress&lt;/code&gt; stopgap. If you run WordPress, remember the fix lives at the PHP layer, so check for compromise as well as patching. Either way, act now rather than waiting on a version number to tell you whether you are safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Help Net Security: &lt;a href="https://www.helpnetsecurity.com/2026/10/21/php2shell-php-vulnerabilities-patched-cve-2026-109618-cve-2026-109619/" rel="noopener noreferrer"&gt;https://www.helpnetsecurity.com/2026/10/21/php2shell-php-vulnerabilities-patched-cve-2026-109618-cve-2026-109619/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Ubuntu: &lt;a href="https://ubuntu.com/blog/php2shell-vulnerability-fixes-available" rel="noopener noreferrer"&gt;https://ubuntu.com/blog/php2shell-vulnerability-fixes-available&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sansec: &lt;a href="https://sansec.io/research/php2shell" rel="noopener noreferrer"&gt;https://sansec.io/research/php2shell&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;JFrog Security Research: &lt;a href="https://research.jfrog.com/post/php2shell-all-you-need-to-know-about-cve-2026-109618-and-cve-2026-109619/" rel="noopener noreferrer"&gt;https://research.jfrog.com/post/php2shell-all-you-need-to-know-about-cve-2026-109618-and-cve-2026-109619/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Datadog Security Labs: &lt;a href="https://securitylabs.datadoghq.com/articles/php2shell-critical-vulnerabilities-in-php/" rel="noopener noreferrer"&gt;https://securitylabs.datadoghq.com/articles/php2shell-critical-vulnerabilities-in-php/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SOCRadar: &lt;a href="https://socradar.io/blog/php2shell-cve-2026-109618-cve-2026-109619/" rel="noopener noreferrer"&gt;https://socradar.io/blog/php2shell-cve-2026-109618-cve-2026-109619/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Brandefense: &lt;a href="https://brandefense.io/blog/php2shell-php-rce-cve-2026-109618-109619/" rel="noopener noreferrer"&gt;https://brandefense.io/blog/php2shell-php-rce-cve-2026-109618-109619/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Qualys: &lt;a href="https://blog.qualys.com/vulnerabilities-threat-research/2026/10/20/php-announces-critical-security-release-for-two-vulnerabilities" rel="noopener noreferrer"&gt;https://blog.qualys.com/vulnerabilities-threat-research/2026/10/20/php-announces-critical-security-release-for-two-vulnerabilities&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Upwind: &lt;a href="https://www.upwind.io/feed/initial-assessment-php2shell-two-critical-unpatched-php-rces-cve-2026-109618-cve-2026-109619" rel="noopener noreferrer"&gt;https://www.upwind.io/feed/initial-assessment-php2shell-two-critical-unpatched-php-rces-cve-2026-109618-cve-2026-109619&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Abstract Security: &lt;a href="https://www.abstract.security/blog/php2shell-critical-php-rce-vulnerabilities-cve-2026-109618-and-cve-2026-109619" rel="noopener noreferrer"&gt;https://www.abstract.security/blog/php2shell-critical-php-rce-vulnerabilities-cve-2026-109618-and-cve-2026-109619&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;php-fix (cPanel and Ubuntu build tables): &lt;a href="https://github.com/ersinkoc/php-fix" rel="noopener noreferrer"&gt;https://github.com/ersinkoc/php-fix&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>linux</category>
      <category>ubuntu</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Understanding WhatsApp Pricing: What Individuals, Businesses, and Developers Need to Know</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Sat, 10 Oct 2026 09:36:30 +0000</pubDate>
      <link>https://dev.to/msnmongare/understanding-whatsapp-pricing-what-individuals-businesses-and-developers-need-to-know-24jg</link>
      <guid>https://dev.to/msnmongare/understanding-whatsapp-pricing-what-individuals-businesses-and-developers-need-to-know-24jg</guid>
      <description>&lt;p&gt;&lt;a href="https://www.whatsapp.com/" rel="noopener noreferrer"&gt;WhatsApp &lt;/a&gt;is one of the most popular messaging platforms in the world. Millions of people use it every day to chat with friends, make voice and video calls, share files, and stay connected with family. For ordinary users, these activities are generally free, provided they have an internet connection.&lt;/p&gt;

&lt;p&gt;But things work differently when businesses use WhatsApp to communicate with customers at scale.&lt;/p&gt;

&lt;p&gt;A business sending order confirmations, payment notifications, verification codes, appointment reminders, or marketing messages may incur messaging costs. The amount depends on the type of message, the customer's country, and whether the business uses Meta's official WhatsApp Business Platform directly or through a third-party provider.&lt;/p&gt;

&lt;p&gt;Understanding these differences is important for businesses planning to use WhatsApp for customer communication, developers building WhatsApp integrations, and entrepreneurs offering WhatsApp messaging services.&lt;/p&gt;

&lt;p&gt;Let's break it down.&lt;/p&gt;

&lt;h2&gt;
  
  
  WhatsApp Is Free for Everyday Users
&lt;/h2&gt;

&lt;p&gt;For individuals, WhatsApp does not charge a fee for every message sent or received. You can send text messages, share photos and documents, and make voice or video calls without paying WhatsApp a per-message charge.&lt;/p&gt;

&lt;p&gt;However, WhatsApp still uses your internet connection. If you are using mobile data, your network provider may charge you for data usage. If you are connected to Wi-Fi, the internet service itself may have a cost.&lt;/p&gt;

&lt;p&gt;WhatsApp also offers the WhatsApp Business app, which small businesses can use to communicate with customers, organize conversations, create product catalogs, and set up automated greetings and away messages.&lt;/p&gt;

&lt;p&gt;The app is generally free to use, although optional business services and related tools may have their own charges.&lt;/p&gt;

&lt;p&gt;The important distinction is that using WhatsApp as an individual or through the standard WhatsApp Business app is not the same as using the official WhatsApp Business Platform, commonly called the WhatsApp API.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is the WhatsApp Business Platform?
&lt;/h2&gt;

&lt;p&gt;The WhatsApp Business Platform is designed for businesses that need to communicate with customers programmatically or at scale.&lt;/p&gt;

&lt;p&gt;For example, an e-commerce business might want to send a WhatsApp message whenever a customer places an order. A fintech company might need to send payment confirmations. A bank might send transaction alerts, while a software application might send one-time passwords during account registration.&lt;/p&gt;

&lt;p&gt;Instead of manually sending each message from a phone, the business connects its systems to WhatsApp through an API.&lt;/p&gt;

&lt;p&gt;This allows applications to send messages automatically in response to events such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A customer completing a payment.&lt;/li&gt;
&lt;li&gt;An order being placed or shipped.&lt;/li&gt;
&lt;li&gt;A user requesting a verification code.&lt;/li&gt;
&lt;li&gt;An appointment being booked.&lt;/li&gt;
&lt;li&gt;A customer asking for support.&lt;/li&gt;
&lt;li&gt;A business launching a promotional campaign.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meta charges businesses under its WhatsApp Business Platform pricing model. Depending on how the business connects to the platform, additional software or provider charges may also apply.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Four WhatsApp Message Categories
&lt;/h2&gt;

&lt;p&gt;WhatsApp Business Platform messaging has four main categories: marketing, utility, authentication, and service.&lt;/p&gt;

&lt;p&gt;Each category serves a different purpose and has different pricing rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Marketing Messages
&lt;/h3&gt;

&lt;p&gt;Marketing messages are used to promote products, services, offers, or customer engagement campaigns.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Get 20% off your next purchase this weekend."&lt;/li&gt;
&lt;li&gt;"We have new products available. Check them out."&lt;/li&gt;
&lt;li&gt;"Come back and complete your shopping."&lt;/li&gt;
&lt;li&gt;"Your favourite items are now on sale."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Marketing messages are generally more expensive than utility messages because they are promotional in nature.&lt;/p&gt;

&lt;p&gt;For businesses, this means that sending marketing messages to thousands of customers can become costly if the campaign is not carefully planned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Utility Messages
&lt;/h3&gt;

&lt;p&gt;Utility messages communicate specific information about a transaction, account, order, or service that a customer has requested or is expecting.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Your order has been confirmed."&lt;/li&gt;
&lt;li&gt;"We have received your payment of KSh 2,500."&lt;/li&gt;
&lt;li&gt;"Your package is out for delivery."&lt;/li&gt;
&lt;li&gt;"Your appointment is scheduled for tomorrow at 10:00 AM."&lt;/li&gt;
&lt;li&gt;"Your monthly statement is ready."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These messages are useful for businesses that need to keep customers informed without requiring manual communication.&lt;/p&gt;

&lt;p&gt;Utility messages generally cost less than marketing messages. However, the message must meet Meta's classification requirements. A business cannot simply label a promotional message as utility to obtain a lower rate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication Messages
&lt;/h3&gt;

&lt;p&gt;Authentication messages help verify a customer's identity or confirm that they control a particular account or phone number.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-time passwords (OTPs).&lt;/li&gt;
&lt;li&gt;Login verification codes.&lt;/li&gt;
&lt;li&gt;Account registration codes.&lt;/li&gt;
&lt;li&gt;Identity verification codes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These messages are particularly useful for fintech applications, e-commerce platforms, and applications that require secure account access.&lt;/p&gt;

&lt;p&gt;Authentication pricing is determined by the applicable market rate and authentication rules. It should not automatically be assumed to match the utility rate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service Messages
&lt;/h3&gt;

&lt;p&gt;Service messages are replies businesses send when customers initiate conversations or request assistance.&lt;/p&gt;

&lt;p&gt;For example, a customer might ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Have you received my payment?"&lt;/li&gt;
&lt;li&gt;"Where is my order?"&lt;/li&gt;
&lt;li&gt;"How do I reset my password?"&lt;/li&gt;
&lt;li&gt;"Can someone help me with my account?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The business can respond through its customer support team or an integrated messaging system.&lt;/p&gt;

&lt;p&gt;Service conversations are particularly important because they allow businesses to provide customer support without treating every interaction like a marketing campaign.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Much Does WhatsApp Business Messaging Cost?
&lt;/h2&gt;

&lt;p&gt;There is no single worldwide price for sending a WhatsApp Business Platform message.&lt;/p&gt;

&lt;p&gt;Meta's rates depend primarily on the recipient's country or market and the message category. Authentication messages may also be subject to additional pricing rules, including international authentication rates where applicable.&lt;/p&gt;

&lt;p&gt;The following figures from the initial research are illustrative estimates, not guaranteed current prices.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Message category&lt;/th&gt;
&lt;th&gt;Estimated US rate&lt;/th&gt;
&lt;th&gt;Estimated Kenya rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;$0.0250&lt;/td&gt;
&lt;td&gt;KSh 3.20-3.30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Utility&lt;/td&gt;
&lt;td&gt;$0.0040&lt;/td&gt;
&lt;td&gt;Around KSh 0.52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;td&gt;Varies&lt;/td&gt;
&lt;td&gt;Verify the applicable rate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;td&gt;Often free within the applicable window&lt;/td&gt;
&lt;td&gt;Often free within the applicable window&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These figures should be checked against Meta's current official rate card before budgeting or publishing a price list. Rates can change, and the effective cost depends on the recipient's market and the applicable billing rules.&lt;/p&gt;

&lt;p&gt;For official information, consult the &lt;a href="https://whatsappbusiness.com/products/platform-pricing/" rel="noopener noreferrer"&gt;WhatsApp Business Platform pricing page&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Simple Cost Example
&lt;/h3&gt;

&lt;p&gt;Imagine a business sends 10,000 marketing messages to customers in Kenya.&lt;/p&gt;

&lt;p&gt;Using an illustrative rate of KSh 3.25 per delivered message:&lt;/p&gt;

&lt;p&gt;10,000 × KSh 3.25 = KSh 32,500.&lt;/p&gt;

&lt;p&gt;The estimated Meta messaging charge would be KSh 32,500, before any provider fees, applicable taxes, or other service charges.&lt;/p&gt;

&lt;p&gt;Now imagine the same business sends 10,000 utility messages at an illustrative rate of KSh 0.52 each.&lt;/p&gt;

&lt;p&gt;10,000 × KSh 0.52 = KSh 5,200.&lt;/p&gt;

&lt;p&gt;That is a substantial difference.&lt;/p&gt;

&lt;p&gt;This example shows why understanding message categories is important. Businesses should design their messaging workflows around the actual purpose of each message rather than assuming all WhatsApp messages cost the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 24-Hour Customer Service Window
&lt;/h2&gt;

&lt;p&gt;One of the most important concepts in WhatsApp pricing is the 24-hour customer service window.&lt;/p&gt;

&lt;p&gt;Whenever a customer sends a message to a business, a 24-hour window opens or resets. During this period, the business can respond using free-form messages without requiring an approved template, subject to WhatsApp's messaging policies.&lt;/p&gt;

&lt;p&gt;However, the pricing rules have changed over time, so businesses need to pay attention to the date of the applicable pricing policy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Important pricing update: October 2026
&lt;/h3&gt;

&lt;p&gt;As of October 1, 2026, Meta introduced changes to service and utility message charges. This means older articles stating that all service replies and utility messages within the 24-hour window are free may no longer be accurate.&lt;/p&gt;

&lt;p&gt;Under the updated rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Service messages:&lt;/strong&gt; Businesses receive an allowance of 1,000 free service messages per business phone number per month. Additional service messages are charged at the applicable rate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utility messages:&lt;/strong&gt; Utility template messages sent within the 24-hour customer service window are now subject to the applicable per-message charge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketing messages:&lt;/strong&gt; Marketing template messages remain chargeable per delivered message.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication messages:&lt;/strong&gt; Authentication template messages remain chargeable at the applicable authentication rate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These changes make it especially important to check current pricing before designing a customer communication system. See the &lt;a href="https://whatsappbusiness.com/products/platform-pricing/" rel="noopener noreferrer"&gt;WhatsApp Business Platform pricing page&lt;/a&gt; and this &lt;a href="https://www.the-star.co.ke/news/2026-08-28-meta-announces-fresh-whatsapp-charges-for-kenyan-businesses" rel="noopener noreferrer"&gt;report on the October 2026 pricing changes in Kenya&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is a WhatsApp Message Template?
&lt;/h2&gt;

&lt;p&gt;A message template is a predefined message that a business submits to Meta for approval before using it in situations where templates are required, particularly when initiating conversations outside the customer service window.&lt;/p&gt;

&lt;p&gt;Templates can contain text, images, buttons, and variables that are replaced with customer-specific information.&lt;/p&gt;

&lt;p&gt;For example, a payment notification template might look like this:&lt;/p&gt;

&lt;p&gt;"Hello {{1}}, we have received your payment of KSh {{2}}. Your transaction reference is {{3}}. Thank you for using our service."&lt;/p&gt;

&lt;p&gt;The placeholders allow the same approved template to be reused for thousands of customers without manually composing each message.&lt;/p&gt;

&lt;p&gt;Templates are generally categorized as marketing, utility, or authentication. Meta determines whether the content qualifies for the requested category.&lt;/p&gt;

&lt;p&gt;A critical point is that &lt;strong&gt;approval does not mean a message is free&lt;/strong&gt;. A template can be approved and still incur a charge every time it is successfully delivered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Are Incoming WhatsApp Messages Free?
&lt;/h2&gt;

&lt;p&gt;Businesses are not charged by Meta simply because a customer sends them an inbound message.&lt;/p&gt;

&lt;p&gt;However, receiving a message can trigger a customer service window, during which the business can respond according to the applicable messaging rules.&lt;/p&gt;

&lt;p&gt;Businesses should distinguish between the cost of receiving a message and the cost of sending a response. They should also check whether their messaging provider charges separately for inbound or outbound traffic.&lt;/p&gt;

&lt;p&gt;For example, Twilio charges its own fee of $0.005 per WhatsApp message, including inbound and outbound messages, in addition to applicable Meta template fees. Other providers have different pricing arrangements.&lt;/p&gt;

&lt;p&gt;This is why a business can incur messaging costs even when Meta does not charge for a particular interaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meta's Charges Versus Third-Party Provider Charges
&lt;/h2&gt;

&lt;p&gt;This is another area that businesses often overlook.&lt;/p&gt;

&lt;p&gt;There are two main cost components when using the WhatsApp Business Platform through a third-party provider.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Meta messaging fees&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are the charges imposed by Meta for eligible delivered template messages and other billable message categories.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Provider or platform fees&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are charges imposed by the software provider that connects the business to WhatsApp. Depending on the provider, they may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A fee per message.&lt;/li&gt;
&lt;li&gt;Monthly subscription charges.&lt;/li&gt;
&lt;li&gt;A fee per WhatsApp number or connected account.&lt;/li&gt;
&lt;li&gt;Charges for team inboxes and customer support tools.&lt;/li&gt;
&lt;li&gt;Additional fees for automation, analytics, or integrations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, a business using &lt;a href="https://www.twilio.com/en-us/whatsapp/pricing" rel="noopener noreferrer"&gt;Twilio's WhatsApp service&lt;/a&gt; may pay both Meta's applicable template fees and Twilio's separate per-message fee.&lt;/p&gt;

&lt;p&gt;Other providers may offer monthly plans, usage-based billing, or a combination of the two.&lt;/p&gt;

&lt;p&gt;Consequently, two businesses sending the same number of WhatsApp messages can pay different total amounts because they use different providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding WhatsApp API Pricing for SaaS Businesses
&lt;/h2&gt;

&lt;p&gt;Suppose you are building a WhatsApp messaging platform for other businesses. Your customers might use your software to send OTPs, payment confirmations, order updates, or group announcements.&lt;/p&gt;

&lt;p&gt;Your pricing model must account for more than Meta's messaging rates.&lt;/p&gt;

&lt;p&gt;Your costs may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meta messaging fees.&lt;/li&gt;
&lt;li&gt;WhatsApp infrastructure and hosting.&lt;/li&gt;
&lt;li&gt;API servers, databases, and background jobs.&lt;/li&gt;
&lt;li&gt;Payment processing fees.&lt;/li&gt;
&lt;li&gt;Customer support.&lt;/li&gt;
&lt;li&gt;Monitoring, maintenance, and security.&lt;/li&gt;
&lt;li&gt;Provider fees, where applicable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you charge customers a flat monthly subscription, you need to estimate how much messaging each customer is likely to consume.&lt;/p&gt;

&lt;p&gt;Consider a simplified example in which your platform charges a customer KSh 1,000 per month.&lt;/p&gt;

&lt;p&gt;If the customer sends 200 marketing messages at an illustrative cost of KSh 3.25 each, the Meta messaging cost alone would be KSh 650.&lt;/p&gt;

&lt;p&gt;That leaves KSh 350 before accounting for hosting, support, payment processing, and other operational expenses.&lt;/p&gt;

&lt;p&gt;If the customer sends 1,000 marketing messages at the same illustrative rate, the Meta messaging cost would be KSh 3,250. A KSh 1,000 subscription would no longer cover the messaging cost.&lt;/p&gt;

&lt;p&gt;This is why messaging platforms need to understand usage patterns and establish sustainable pricing models.&lt;/p&gt;

&lt;p&gt;Possible approaches include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monthly subscriptions with reasonable usage limits.&lt;/li&gt;
&lt;li&gt;Pay-as-you-go pricing.&lt;/li&gt;
&lt;li&gt;Prepaid messaging credits.&lt;/li&gt;
&lt;li&gt;Subscription plans with included message allowances and additional usage charges.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The right model depends on your target customers, expected message volumes, and operating costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Businesses Can Reduce WhatsApp Messaging Costs
&lt;/h2&gt;

&lt;p&gt;WhatsApp can be a valuable communication channel, but poorly designed messaging workflows can create unnecessary expenses.&lt;/p&gt;

&lt;p&gt;Here are several practical ways to manage costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Send messages that serve a clear purpose
&lt;/h3&gt;

&lt;p&gt;Avoid sending unnecessary notifications. A customer may need a payment confirmation, but they might not need several messages repeating the same information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose the correct message category
&lt;/h3&gt;

&lt;p&gt;Use utility messages for genuine transactional updates, marketing messages for promotions, and authentication messages for verification.&lt;/p&gt;

&lt;p&gt;Do not misclassify messages to obtain cheaper rates. Meta may reclassify templates that do not meet its requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitor delivered messages
&lt;/h3&gt;

&lt;p&gt;Meta's fees generally depend on billable messages being delivered, not simply on attempts to send them. Monitor delivery-status webhooks and your billing reports to understand actual usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Track costs by customer and use case
&lt;/h3&gt;

&lt;p&gt;If you operate a messaging SaaS, measure how much each customer spends on OTPs, notifications, and marketing campaigns.&lt;/p&gt;

&lt;p&gt;This helps you identify expensive accounts and adjust subscription limits before your margins become negative.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use customer-initiated conversations appropriately
&lt;/h3&gt;

&lt;p&gt;Customer support remains an important use case for WhatsApp. However, because the pricing rules can change, do not assume every reply within the 24-hour window is free.&lt;/p&gt;

&lt;p&gt;Check the current rules for the message category and your provider's fees.&lt;/p&gt;

&lt;h3&gt;
  
  
  Take advantage of volume-based pricing where available
&lt;/h3&gt;

&lt;p&gt;Meta offers volume-based pricing tiers for certain utility and authentication messages. Eligible businesses may receive lower rates as their qualifying message volumes increase.&lt;/p&gt;

&lt;p&gt;The applicable thresholds and discounts vary by market and category, so consult the current rate card.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Misconceptions About WhatsApp Pricing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Myth: All WhatsApp messages are free.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reality: Ordinary personal messaging is generally free of WhatsApp per-message charges, but businesses using the official platform may pay for delivered messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Myth: Every WhatsApp API message costs the same.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reality: Rates vary by message category, recipient's market, and applicable pricing rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Myth: All customer support replies are free.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reality: The rules changed in October 2026. Businesses should account for the monthly free service allowance and applicable charges beyond it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Myth: The WhatsApp Business app and WhatsApp Business Platform are the same product.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reality: The Business app is designed for managing customer conversations through an app, while the Business Platform supports programmatic messaging and integrations at scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Myth: Using an official API provider eliminates Meta messaging charges.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reality: An official provider does not automatically eliminate Meta's fees. Provider fees may be added on top of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Myth: A message template is free once approved.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reality: Approval allows the template to be used, but billable messages can still incur charges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Understanding WhatsApp pricing is essential for anyone building a business around WhatsApp messaging or integrating it into an existing application.&lt;/p&gt;

&lt;p&gt;The most important thing to remember is that there is no single universal price for WhatsApp messages. Costs depend on how you use the platform, the type of message you send, the customer's country, the applicable pricing rules, and any additional charges imposed by your provider.&lt;/p&gt;

&lt;p&gt;For developers, the lesson is to design systems that track message categories, delivery statuses, and usage costs from the beginning.&lt;/p&gt;

&lt;p&gt;For business owners, it is to understand the total cost of communicating with customers before choosing a subscription or launching a large messaging campaign.&lt;/p&gt;

&lt;p&gt;And for SaaS founders, it is to make sure that the price customers pay covers both messaging costs and the operational expenses of running the platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before setting a budget or publishing a price list, always check Meta's latest rate card and your provider's pricing terms.&lt;/strong&gt; WhatsApp pricing changes over time, and a pricing model that worked last year may not be profitable today.&lt;/p&gt;

</description>
      <category>whatsapp</category>
      <category>twilio</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>AI Is Generally Not What the Average Person Thinks It Is</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Thu, 08 Oct 2026 11:38:46 +0000</pubDate>
      <link>https://dev.to/msnmongare/ai-is-generally-not-what-the-average-person-thinks-it-is-576i</link>
      <guid>https://dev.to/msnmongare/ai-is-generally-not-what-the-average-person-thinks-it-is-576i</guid>
      <description>&lt;p&gt;Artificial Intelligence is everywhere.&lt;/p&gt;

&lt;p&gt;It writes emails, generates images, writes code, recommends what we watch, detects fraud, translates languages, answers questions, drives vehicles, analyzes medical images, and increasingly interacts with software on our behalf.&lt;/p&gt;

&lt;p&gt;And yet, there is a good chance that many people have the wrong mental model of what AI actually is.&lt;/p&gt;

&lt;p&gt;Ask the average person what AI is, and you may hear descriptions of a machine that thinks like a human, understands everything, has its own intentions, or is slowly becoming conscious.&lt;/p&gt;

&lt;p&gt;That picture has been shaped by science fiction, movies, sensational headlines, and increasingly aggressive AI marketing.&lt;/p&gt;

&lt;p&gt;The reality is both less magical and, in some ways, more impressive.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI is not one thing
&lt;/h2&gt;

&lt;p&gt;One of the first misconceptions is treating "AI" as if it were a single technology.&lt;/p&gt;

&lt;p&gt;It is not.&lt;/p&gt;

&lt;p&gt;Artificial Intelligence is a broad field of computing focused on building systems that can perform tasks that traditionally require some form of human intelligence.&lt;/p&gt;

&lt;p&gt;Machine learning is one approach to building AI systems. Instead of explicitly programming every rule, we train models to identify patterns from data.&lt;/p&gt;

&lt;p&gt;Deep learning is a subset of machine learning that uses neural networks with many layers.&lt;/p&gt;

&lt;p&gt;Generative AI is another category of AI systems that can generate new content such as text, images, audio, video, and code.&lt;/p&gt;

&lt;p&gt;Large Language Models, such as the models behind ChatGPT, are specifically designed to work with language and related modalities.&lt;/p&gt;

&lt;p&gt;So when someone says "AI," they could be talking about a recommendation algorithm, a fraud detection system, a computer vision model, a voice recognition system, a self-driving system, or a large language model.&lt;/p&gt;

&lt;p&gt;They are not all doing the same thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The biggest misconception: AI is a digital human
&lt;/h2&gt;

&lt;p&gt;This is probably the biggest gap between perception and reality.&lt;/p&gt;

&lt;p&gt;People often interact with an AI system and think:&lt;/p&gt;

&lt;p&gt;"It understands me."&lt;/p&gt;

&lt;p&gt;"It knows what I mean."&lt;/p&gt;

&lt;p&gt;"It thinks about the problem."&lt;/p&gt;

&lt;p&gt;"It wants to help me."&lt;/p&gt;

&lt;p&gt;"It knows that it is wrong."&lt;/p&gt;

&lt;p&gt;The interaction can certainly feel that way.&lt;/p&gt;

&lt;p&gt;But human-like interaction does not necessarily mean human-like cognition.&lt;/p&gt;

&lt;p&gt;Modern AI systems can produce remarkably convincing outputs without possessing human consciousness, emotions, personal experiences, or desires.&lt;/p&gt;

&lt;p&gt;A language model, for example, processes representations of language and calculates probabilities over possible outputs based on patterns learned during training and the context provided to it.&lt;/p&gt;

&lt;p&gt;That is very different from a human sitting down and consciously thinking through an answer.&lt;/p&gt;

&lt;p&gt;And this distinction matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI does not have to think like us to be useful
&lt;/h2&gt;

&lt;p&gt;There is another misconception hidden inside the first one.&lt;/p&gt;

&lt;p&gt;People sometimes assume that if AI does not think exactly like a human, then it is somehow fake or not truly intelligent.&lt;/p&gt;

&lt;p&gt;That is the wrong comparison.&lt;/p&gt;

&lt;p&gt;An aircraft does not fly like a bird.&lt;/p&gt;

&lt;p&gt;A calculator does not calculate like a mathematician.&lt;/p&gt;

&lt;p&gt;A database does not remember like a human.&lt;/p&gt;

&lt;p&gt;Yet all of them perform useful functions extremely well.&lt;/p&gt;

&lt;p&gt;AI does not need to reproduce the human mind to perform tasks that previously required human intelligence.&lt;/p&gt;

&lt;p&gt;In some tasks, it can already outperform humans.&lt;/p&gt;

&lt;p&gt;It can process enormous amounts of information, identify patterns across large datasets, generate thousands of variations, analyze documents at scale, and perform repetitive operations far faster than a person.&lt;/p&gt;

&lt;p&gt;The important question is therefore not:&lt;/p&gt;

&lt;p&gt;"Does AI think exactly like a human?"&lt;/p&gt;

&lt;p&gt;The more useful question is:&lt;/p&gt;

&lt;p&gt;"What can this system reliably do?"&lt;/p&gt;

&lt;h2&gt;
  
  
  AI is not always "learning" while you talk to it
&lt;/h2&gt;

&lt;p&gt;Another common misconception is that an AI is continuously learning from every conversation in the same way a human learns from experience.&lt;/p&gt;

&lt;p&gt;Usually, that is not what is happening.&lt;/p&gt;

&lt;p&gt;A model is trained using large amounts of data during a training process. The training process adjusts the model's parameters so that it becomes better at recognizing patterns and producing useful outputs.&lt;/p&gt;

&lt;p&gt;When you send a prompt, the model generally uses its existing parameters together with the context available in that interaction to generate a response.&lt;/p&gt;

&lt;p&gt;That is different from a human who continuously forms memories, develops beliefs, and accumulates personal experiences.&lt;/p&gt;

&lt;p&gt;Some AI products can have memory features, retrieval systems, tools, or mechanisms that allow them to use information from previous interactions. But that still does not mean the underlying model is spontaneously developing a human-like consciousness.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "autocomplete" explanation is useful - but incomplete
&lt;/h2&gt;

&lt;p&gt;You have probably heard the statement:&lt;/p&gt;

&lt;p&gt;"AI is just autocomplete."&lt;/p&gt;

&lt;p&gt;There is some truth in this explanation, particularly when describing how language models generate text.&lt;/p&gt;

&lt;p&gt;At a fundamental level, a language model predicts what tokens are likely to come next based on the context it has received.&lt;/p&gt;

&lt;p&gt;That sounds simple.&lt;/p&gt;

&lt;p&gt;But "just autocomplete" can also be misleading.&lt;/p&gt;

&lt;p&gt;Modern models learn extremely complex statistical relationships from enormous datasets. Those relationships can allow models to perform translation, summarization, coding, reasoning-like tasks, classification, information extraction, and many other activities.&lt;/p&gt;

&lt;p&gt;So comparing an advanced language model to the autocomplete on your phone is useful for explaining the basic mechanism, but it dramatically understates the complexity and capabilities involved.&lt;/p&gt;

&lt;p&gt;It is better to think of it as:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autocomplete at an enormous scale, with learned representations that enable surprisingly sophisticated behavior.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And even that describes only one part of AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI can be extremely capable and still be wrong
&lt;/h2&gt;

&lt;p&gt;This is another important misconception.&lt;/p&gt;

&lt;p&gt;Many people assume that if an AI sounds confident, it must know what it is talking about.&lt;/p&gt;

&lt;p&gt;It doesn't.&lt;/p&gt;

&lt;p&gt;AI systems can produce incorrect information while presenting it in a very convincing way.&lt;/p&gt;

&lt;p&gt;Large language models can "hallucinate" - generating information that sounds plausible but is factually incorrect.&lt;/p&gt;

&lt;p&gt;This happens because generating a convincing answer and retrieving objective truth are not necessarily the same thing.&lt;/p&gt;

&lt;p&gt;The model's objective is not simply:&lt;/p&gt;

&lt;p&gt;"Always tell the truth."&lt;/p&gt;

&lt;p&gt;Its behavior depends on how it was trained, the information available to it, the instructions it receives, and the tools it can access.&lt;/p&gt;

&lt;p&gt;This is why AI output should not automatically be treated as authoritative.&lt;/p&gt;

&lt;p&gt;The more important the decision, the more important verification becomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI can also be biased
&lt;/h2&gt;

&lt;p&gt;AI does not magically remove human bias.&lt;/p&gt;

&lt;p&gt;AI systems are created, trained, evaluated, deployed, and used by humans.&lt;/p&gt;

&lt;p&gt;Their data comes from human-created information.&lt;/p&gt;

&lt;p&gt;That means AI systems can inherit biases, gaps, errors, and assumptions from the data and processes used to build them.&lt;/p&gt;

&lt;p&gt;This does not mean every AI system is equally biased or that AI is inherently unreliable.&lt;/p&gt;

&lt;p&gt;It means that "AI said it" is not a substitute for asking:&lt;/p&gt;

&lt;p&gt;Where did this information come from?&lt;/p&gt;

&lt;p&gt;What data was used?&lt;/p&gt;

&lt;p&gt;How was the system evaluated?&lt;/p&gt;

&lt;p&gt;What assumptions are built into it?&lt;/p&gt;

&lt;p&gt;What happens when it encounters something outside its experience?&lt;/p&gt;

&lt;p&gt;Those questions become increasingly important as AI moves into areas such as healthcare, finance, employment, security, and government.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI is not necessarily AGI
&lt;/h2&gt;

&lt;p&gt;Another misconception is that today's AI systems are already Artificial General Intelligence.&lt;/p&gt;

&lt;p&gt;They are not.&lt;/p&gt;

&lt;p&gt;AGI generally refers to a hypothetical level of AI capable of performing a broad range of intellectual tasks with a level of flexibility comparable to humans, rather than being highly capable in a narrower set of domains.&lt;/p&gt;

&lt;p&gt;Today's AI systems can be astonishingly capable while still having significant limitations.&lt;/p&gt;

&lt;p&gt;A model might write excellent code but struggle with a seemingly simple real-world task.&lt;/p&gt;

&lt;p&gt;It might summarize a 200-page document in seconds but confidently misunderstand an important detail.&lt;/p&gt;

&lt;p&gt;It might solve a difficult mathematical problem but fail at something that a child can do effortlessly.&lt;/p&gt;

&lt;p&gt;This is one of the strange characteristics of modern AI:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capability can be extremely high in one area and surprisingly weak in another.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is very different from the flexible intelligence of a human being.&lt;/p&gt;

&lt;h2&gt;
  
  
  The most interesting part of AI is not consciousness
&lt;/h2&gt;

&lt;p&gt;The discussion around whether AI is conscious gets enormous attention.&lt;/p&gt;

&lt;p&gt;But from a practical perspective, I think we sometimes focus on the wrong question.&lt;/p&gt;

&lt;p&gt;You do not need an AI system to be conscious for it to fundamentally change how businesses operate.&lt;/p&gt;

&lt;p&gt;Consider what happens if software can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read thousands of documents.&lt;/li&gt;
&lt;li&gt;Extract structured information from them.&lt;/li&gt;
&lt;li&gt;Classify incoming requests.&lt;/li&gt;
&lt;li&gt;Write and send responses.&lt;/li&gt;
&lt;li&gt;Call APIs.&lt;/li&gt;
&lt;li&gt;Query databases.&lt;/li&gt;
&lt;li&gt;Generate reports.&lt;/li&gt;
&lt;li&gt;Monitor systems.&lt;/li&gt;
&lt;li&gt;Trigger workflows.&lt;/li&gt;
&lt;li&gt;Analyze images.&lt;/li&gt;
&lt;li&gt;Write and review code.&lt;/li&gt;
&lt;li&gt;Interact with business applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that requires a robot with feelings.&lt;/p&gt;

&lt;p&gt;It requires software that can perceive information, make useful predictions or decisions, use tools, and execute actions within defined boundaries.&lt;/p&gt;

&lt;p&gt;That is already powerful enough to transform entire workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real AI revolution may be less dramatic than movies - and more important
&lt;/h2&gt;

&lt;p&gt;Hollywood gives us robots, humanoids, autonomous machines, and superintelligent systems taking over the world.&lt;/p&gt;

&lt;p&gt;The actual AI revolution may look much more ordinary.&lt;/p&gt;

&lt;p&gt;It might be an employee who previously spent six hours preparing a report now doing it in thirty minutes.&lt;/p&gt;

&lt;p&gt;It might be a developer generating a first implementation, then spending more time reviewing architecture, security, tests, and business logic.&lt;/p&gt;

&lt;p&gt;It might be a customer support system handling routine requests while humans deal with complex cases.&lt;/p&gt;

&lt;p&gt;It might be an insurance company processing documents automatically.&lt;/p&gt;

&lt;p&gt;It might be a small business using AI to analyze its customers, automate follow-ups, generate content, and operate workflows that previously required several employees.&lt;/p&gt;

&lt;p&gt;The transformation may not look like science fiction.&lt;/p&gt;

&lt;p&gt;It may simply look like software becoming much more capable.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI is a tool, not magic
&lt;/h2&gt;

&lt;p&gt;Perhaps the healthiest mental model is to stop thinking of AI as magic.&lt;/p&gt;

&lt;p&gt;AI is technology.&lt;/p&gt;

&lt;p&gt;Very sophisticated technology, but still technology.&lt;/p&gt;

&lt;p&gt;It has capabilities.&lt;/p&gt;

&lt;p&gt;It has limitations.&lt;/p&gt;

&lt;p&gt;It can amplify human productivity.&lt;/p&gt;

&lt;p&gt;It can also amplify human mistakes.&lt;/p&gt;

&lt;p&gt;It can automate tasks.&lt;/p&gt;

&lt;p&gt;It can create new risks.&lt;/p&gt;

&lt;p&gt;It can produce remarkably useful results.&lt;/p&gt;

&lt;p&gt;It can also confidently produce nonsense.&lt;/p&gt;

&lt;p&gt;The people who understand this distinction will probably use AI more effectively than those who either worship it or dismiss it.&lt;/p&gt;

&lt;p&gt;You do not need to believe that AI is conscious to take it seriously.&lt;/p&gt;

&lt;p&gt;And you do not need to believe that AI is going to replace everyone to recognize that it will change how many people work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The better question to ask
&lt;/h2&gt;

&lt;p&gt;Instead of asking:&lt;/p&gt;

&lt;p&gt;"Is AI actually intelligent?"&lt;/p&gt;

&lt;p&gt;A more useful set of questions is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is this AI system capable of?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What data does it rely on?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where does it fail?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How can I verify its output?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What tasks should I give it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What tasks should remain under human control?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens when the AI makes a mistake?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These questions move the conversation away from science fiction and toward engineering.&lt;/p&gt;

&lt;p&gt;And that is where the real value of AI is.&lt;/p&gt;

&lt;p&gt;AI does not have to be a conscious digital person to be transformative.&lt;/p&gt;

&lt;p&gt;It only needs to be capable enough to change what software can do, how businesses operate, and how humans work.&lt;/p&gt;

&lt;p&gt;And we are already seeing that happen.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Getting started with Automations</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Wed, 07 Oct 2026 07:09:26 +0000</pubDate>
      <link>https://dev.to/msnmongare/getting-started-with-automations-55be</link>
      <guid>https://dev.to/msnmongare/getting-started-with-automations-55be</guid>
      <description>&lt;p&gt;Automation can sound like something reserved for software engineers, large companies, or people building complicated robots.&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;If you have ever created an email filter, scheduled a message, used a shortcut on your phone, or had one application automatically send information to another, you have already experienced automation.&lt;/p&gt;

&lt;p&gt;At its simplest, &lt;strong&gt;automation means getting technology to perform a task automatically instead of doing it manually every time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add AI to the picture, and automation becomes even more powerful. Instead of simply following fixed instructions, an automated system can use AI to understand text, classify information, summarize documents, extract data, answer questions, and make decisions based on defined rules.&lt;/p&gt;

&lt;p&gt;This guide is for beginners who want to understand automation and AI without getting overwhelmed by technical jargon.&lt;/p&gt;




&lt;h2&gt;
  
  
  First, what exactly is automation?
&lt;/h2&gt;

&lt;p&gt;Imagine that every time someone fills out a contact form on your website, you manually:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the form submission.&lt;/li&gt;
&lt;li&gt;Copy the person's name and email.&lt;/li&gt;
&lt;li&gt;Add them to a spreadsheet.&lt;/li&gt;
&lt;li&gt;Send them a welcome email.&lt;/li&gt;
&lt;li&gt;Notify your sales team.&lt;/li&gt;
&lt;li&gt;Create a follow-up task.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If this happens once, it is not a big deal.&lt;/p&gt;

&lt;p&gt;If it happens 50 times a day, it becomes repetitive work.&lt;/p&gt;

&lt;p&gt;Automation allows you to tell a computer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Whenever someone submits this form, do these things automatically."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the fundamental idea.&lt;/p&gt;

&lt;p&gt;A simple automation can often be described as:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When X happens, do Y.&lt;/strong&gt;&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;When a customer submits a form, add them to Google Sheets and send them a welcome email.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This introduces two concepts that you will see everywhere in automation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trigger&lt;/strong&gt; - the event that starts the automation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action&lt;/strong&gt; - what the automation does after the trigger happens.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;Trigger:&lt;/strong&gt; New customer submits a form&lt;br&gt;
&lt;strong&gt;Action:&lt;/strong&gt; Save customer details to a spreadsheet&lt;/p&gt;

&lt;p&gt;You can then add more actions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trigger:&lt;/strong&gt; New customer submits a form&lt;br&gt;
&lt;strong&gt;Action 1:&lt;/strong&gt; Save their details&lt;br&gt;
&lt;strong&gt;Action 2:&lt;/strong&gt; Send a welcome email&lt;br&gt;
&lt;strong&gt;Action 3:&lt;/strong&gt; Notify the sales team&lt;br&gt;
&lt;strong&gt;Action 4:&lt;/strong&gt; Create a follow-up task&lt;/p&gt;

&lt;p&gt;This is called a &lt;strong&gt;workflow&lt;/strong&gt;.&lt;/p&gt;


&lt;h1&gt;
  
  
  Why should you learn automation?
&lt;/h1&gt;

&lt;p&gt;Most people don't spend their working day doing difficult tasks.&lt;/p&gt;

&lt;p&gt;A surprising amount of time goes into things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copying information between systems&lt;/li&gt;
&lt;li&gt;Sending repetitive emails&lt;/li&gt;
&lt;li&gt;Updating spreadsheets&lt;/li&gt;
&lt;li&gt;Creating reports&lt;/li&gt;
&lt;li&gt;Downloading and renaming files&lt;/li&gt;
&lt;li&gt;Moving data from one application to another&lt;/li&gt;
&lt;li&gt;Sending reminders&lt;/li&gt;
&lt;li&gt;Checking whether something has happened&lt;/li&gt;
&lt;li&gt;Creating the same documents repeatedly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tasks may be necessary, but they don't always require a human.&lt;/p&gt;

&lt;p&gt;Automation allows you to move from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I do this every day."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The system does this for me."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That can save time, reduce human error, and allow people to focus on work that actually requires judgment and creativity.&lt;/p&gt;


&lt;h1&gt;
  
  
  The basic building blocks of automation
&lt;/h1&gt;

&lt;p&gt;Before learning any particular automation tool, understand these concepts.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Trigger
&lt;/h2&gt;

&lt;p&gt;The trigger starts your workflow.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new email arrives&lt;/li&gt;
&lt;li&gt;Someone submits a form&lt;/li&gt;
&lt;li&gt;A payment is received&lt;/li&gt;
&lt;li&gt;A new row is added to a spreadsheet&lt;/li&gt;
&lt;li&gt;A customer creates an account&lt;/li&gt;
&lt;li&gt;A file is uploaded&lt;/li&gt;
&lt;li&gt;It becomes 8:00 AM&lt;/li&gt;
&lt;li&gt;An API receives a request&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of the trigger as:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Something happened."&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Action
&lt;/h2&gt;

&lt;p&gt;An action is something the automation does after the trigger.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send an email&lt;/li&gt;
&lt;li&gt;Create a database record&lt;/li&gt;
&lt;li&gt;Send a WhatsApp notification&lt;/li&gt;
&lt;li&gt;Add a row to Excel&lt;/li&gt;
&lt;li&gt;Create a calendar event&lt;/li&gt;
&lt;li&gt;Upload a file&lt;/li&gt;
&lt;li&gt;Call an API&lt;/li&gt;
&lt;li&gt;Generate a report&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Because that happened, do this."&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Condition
&lt;/h2&gt;

&lt;p&gt;Sometimes you don't want an automation to run the same way every time.&lt;/p&gt;

&lt;p&gt;You can introduce conditions.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;When a new customer signs up, check their country.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If country = Kenya:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Send the Kenyan onboarding message.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If country = Uganda:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Send the Ugandan onboarding message.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Conditions allow your automation to make decisions based on information available to it.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. Data
&lt;/h2&gt;

&lt;p&gt;Automations are usually moving or transforming data.&lt;/p&gt;

&lt;p&gt;For example, a form submission might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name: Jane Doe
Email: jane@example.com
Country: Kenya
Plan: Premium
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your automation might take that information and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store it in a database&lt;/li&gt;
&lt;li&gt;Send an email&lt;/li&gt;
&lt;li&gt;Create a CRM contact&lt;/li&gt;
&lt;li&gt;Notify a salesperson&lt;/li&gt;
&lt;li&gt;Send a WhatsApp message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding how data moves between systems is one of the most important skills in automation.&lt;/p&gt;




&lt;h1&gt;
  
  
  The major types of automation
&lt;/h1&gt;

&lt;p&gt;There are many ways to categorize automation, but beginners can think about them in a few broad areas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflow and integration automation
&lt;/h2&gt;

&lt;p&gt;This is probably the easiest place to start.&lt;/p&gt;

&lt;p&gt;You connect different applications so they can work together automatically.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;New website lead -&amp;gt; Google Sheets -&amp;gt; CRM -&amp;gt; Email notification&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Payment received -&amp;gt; Update database -&amp;gt; Send confirmation -&amp;gt; Notify business owner&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Popular tools include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zapier&lt;/li&gt;
&lt;li&gt;Make&lt;/li&gt;
&lt;li&gt;Microsoft Power Automate&lt;/li&gt;
&lt;li&gt;n8n&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important thing is not memorizing the tools.&lt;/p&gt;

&lt;p&gt;Understand the pattern:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trigger -&amp;gt; Process -&amp;gt; Action&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Personal productivity automation
&lt;/h1&gt;

&lt;p&gt;Automation doesn't have to be for a company.&lt;/p&gt;

&lt;p&gt;You can automate your own digital life.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Automatically filter newsletters from your inbox&lt;/li&gt;
&lt;li&gt;Rename downloaded files&lt;/li&gt;
&lt;li&gt;Create reminders&lt;/li&gt;
&lt;li&gt;Automatically organize documents&lt;/li&gt;
&lt;li&gt;Use keyboard shortcuts for frequently typed text&lt;/li&gt;
&lt;li&gt;Schedule recurring tasks&lt;/li&gt;
&lt;li&gt;Automatically back up files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tools such as Apple Shortcuts, Windows Task Scheduler, Alfred, and built-in email rules can help with this.&lt;/p&gt;

&lt;p&gt;The best automation is often a small one that removes an annoying task you repeatedly perform.&lt;/p&gt;




&lt;h1&gt;
  
  
  Marketing and customer automation
&lt;/h1&gt;

&lt;p&gt;Businesses use automation heavily for marketing and customer communication.&lt;/p&gt;

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

&lt;p&gt;A customer signs up for your product.&lt;/p&gt;

&lt;p&gt;Your system can automatically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the customer account.&lt;/li&gt;
&lt;li&gt;Send a welcome email.&lt;/li&gt;
&lt;li&gt;Add them to your CRM.&lt;/li&gt;
&lt;li&gt;Send onboarding information.&lt;/li&gt;
&lt;li&gt;Wait three days.&lt;/li&gt;
&lt;li&gt;Check whether they have used the product.&lt;/li&gt;
&lt;li&gt;Send another message if they haven't.&lt;/li&gt;
&lt;li&gt;Notify a sales representative if they become highly engaged.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tools such as HubSpot, Mailchimp, ActiveCampaign, and other CRM and marketing platforms provide these capabilities.&lt;/p&gt;

&lt;p&gt;This is particularly useful when you have hundreds or thousands of customers.&lt;/p&gt;




&lt;h1&gt;
  
  
  Robotic Process Automation
&lt;/h1&gt;

&lt;p&gt;Sometimes a business doesn't have an API or easy integration between two systems.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Robotic Process Automation (RPA)&lt;/strong&gt; can be useful.&lt;/p&gt;

&lt;p&gt;Instead of integrating directly with an application, an RPA bot can interact with the application's interface.&lt;/p&gt;

&lt;p&gt;It can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open an application&lt;/li&gt;
&lt;li&gt;Click buttons&lt;/li&gt;
&lt;li&gt;Read information&lt;/li&gt;
&lt;li&gt;Copy data&lt;/li&gt;
&lt;li&gt;Fill in forms&lt;/li&gt;
&lt;li&gt;Download files&lt;/li&gt;
&lt;li&gt;Upload documents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tools such as UiPath and Power Automate Desktop are commonly used for this type of automation.&lt;/p&gt;

&lt;p&gt;However, don't automatically choose RPA just because it can imitate a human.&lt;/p&gt;

&lt;p&gt;If a reliable API exists, an API integration is often more robust than automating clicks on a screen.&lt;/p&gt;




&lt;h1&gt;
  
  
  Where does AI fit into automation?
&lt;/h1&gt;

&lt;p&gt;This is where things get interesting.&lt;/p&gt;

&lt;p&gt;Traditional automation is usually good at following explicit instructions.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;If payment status is "successful", send a confirmation message.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There isn't much ambiguity.&lt;/p&gt;

&lt;p&gt;AI becomes useful when the system needs to &lt;strong&gt;understand something&lt;/strong&gt;.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Read this customer email and determine whether the customer is asking for a refund, reporting a technical problem, or asking about pricing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A traditional automation may struggle with this because emails can be written in thousands of different ways.&lt;/p&gt;

&lt;p&gt;An AI model can interpret the text and classify it.&lt;/p&gt;

&lt;p&gt;The automation can then continue based on the result.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;New email arrives&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI reads the email&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Classify the request&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;If refund request -&amp;gt; send to finance&lt;/p&gt;

&lt;p&gt;If technical issue -&amp;gt; create support ticket&lt;/p&gt;

&lt;p&gt;If sales inquiry -&amp;gt; notify sales&lt;/p&gt;

&lt;p&gt;This combination is often called &lt;strong&gt;AI automation&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Automation vs AI automation
&lt;/h1&gt;

&lt;p&gt;It helps to understand the difference.&lt;/p&gt;

&lt;h3&gt;
  
  
  Traditional automation
&lt;/h3&gt;

&lt;p&gt;The system follows predefined rules.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If X happens, do Y.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;If an invoice is paid, send a receipt.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  AI automation
&lt;/h3&gt;

&lt;p&gt;AI handles a task that requires some level of interpretation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Understand X, determine what it means, then do Y.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Read the customer's message, determine what they need, and route it to the correct department.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The two can work together.&lt;/p&gt;

&lt;p&gt;In fact, some of the most useful systems combine both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automation provides the workflow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI provides intelligence within the workflow.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  A simple AI automation example
&lt;/h1&gt;

&lt;p&gt;Imagine a company receives 200 customer emails every day.&lt;/p&gt;

&lt;p&gt;A basic automation could detect new emails.&lt;/p&gt;

&lt;p&gt;AI can then analyze each email.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New email
   |
   v
AI reads email
   |
   v
Classify request
   |
   +---- Refund ------&amp;gt; Finance
   |
   +---- Technical ---&amp;gt; Support
   |
   +---- Sales -------&amp;gt; Sales team
   |
   +---- General -----&amp;gt; Customer service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could then automatically create tickets, notify employees, summarize the conversation, or draft a response.&lt;/p&gt;

&lt;p&gt;The human can still remain in control.&lt;/p&gt;

&lt;p&gt;AI does not necessarily have to replace the human.&lt;/p&gt;

&lt;p&gt;It can simply remove the repetitive work around the human.&lt;/p&gt;




&lt;h1&gt;
  
  
  You don't need to start with AI
&lt;/h1&gt;

&lt;p&gt;This is important for beginners.&lt;/p&gt;

&lt;p&gt;Don't start by trying to build an autonomous AI agent that controls your entire business.&lt;/p&gt;

&lt;p&gt;Start with automation.&lt;/p&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trigger -&amp;gt; Data -&amp;gt; Condition -&amp;gt; Action&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then introduce AI when you encounter a problem that requires understanding or judgment.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"I can automatically collect these emails, but I need something to understand what each email is about."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a good place for AI.&lt;/p&gt;




&lt;h1&gt;
  
  
  No-code, low-code, or code?
&lt;/h1&gt;

&lt;p&gt;There are three common ways to build automations.&lt;/p&gt;

&lt;h2&gt;
  
  
  No-code automation
&lt;/h2&gt;

&lt;p&gt;You use a visual interface instead of writing code.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zapier&lt;/li&gt;
&lt;li&gt;Make&lt;/li&gt;
&lt;li&gt;Microsoft Power Automate&lt;/li&gt;
&lt;li&gt;IFTTT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You might build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New Gmail email
       |
       v
Check attachment
       |
       v
Save to OneDrive
       |
       v
Send notification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an excellent way for beginners to understand automation concepts.&lt;/p&gt;




&lt;h1&gt;
  
  
  Low-code automation
&lt;/h1&gt;

&lt;p&gt;Low-code tools allow you to use visual workflows while adding expressions, scripts, or custom logic when necessary.&lt;/p&gt;

&lt;p&gt;This gives you more flexibility without requiring you to build everything from scratch.&lt;/p&gt;

&lt;p&gt;For example, you might use Power Automate to create the workflow but write an expression to transform a date or calculate a value.&lt;/p&gt;




&lt;h1&gt;
  
  
  Code-based automation
&lt;/h1&gt;

&lt;p&gt;Once you need more control, you can build automations using code.&lt;/p&gt;

&lt;p&gt;Python is an excellent language for automation because it has a huge ecosystem of libraries and is relatively easy to learn.&lt;/p&gt;

&lt;p&gt;You can use code to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call APIs&lt;/li&gt;
&lt;li&gt;Process files&lt;/li&gt;
&lt;li&gt;Clean data&lt;/li&gt;
&lt;li&gt;Interact with databases&lt;/li&gt;
&lt;li&gt;Scrape websites where permitted&lt;/li&gt;
&lt;li&gt;Send emails&lt;/li&gt;
&lt;li&gt;Process spreadsheets&lt;/li&gt;
&lt;li&gt;Integrate AI models&lt;/li&gt;
&lt;li&gt;Build scheduled jobs&lt;/li&gt;
&lt;li&gt;Create custom automation services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, a Python program could retrieve transactions from an API, analyze them, store the results in a database, and send a daily report.&lt;/p&gt;




&lt;h1&gt;
  
  
  Three common ways to automate with code
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. API integrations
&lt;/h2&gt;

&lt;p&gt;APIs allow software applications to communicate with each other.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Python application
        |
        v
Payment API
        |
        v
Transaction data
        |
        v
Your database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use Python libraries such as &lt;code&gt;requests&lt;/code&gt;, &lt;code&gt;json&lt;/code&gt;, and official SDKs to communicate with APIs.&lt;/p&gt;

&lt;p&gt;If you understand APIs, you already have one of the most valuable foundations for building automations.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Browser automation
&lt;/h1&gt;

&lt;p&gt;Sometimes a website does not provide an API that you can use.&lt;/p&gt;

&lt;p&gt;Browser automation tools can control a browser programmatically.&lt;/p&gt;

&lt;p&gt;Popular tools include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Playwright&lt;/li&gt;
&lt;li&gt;Selenium&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, a permitted internal workflow could:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open a website.&lt;/li&gt;
&lt;li&gt;Log in.&lt;/li&gt;
&lt;li&gt;Search for a record.&lt;/li&gt;
&lt;li&gt;Extract information.&lt;/li&gt;
&lt;li&gt;Save the information.&lt;/li&gt;
&lt;li&gt;Generate a report.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, browser automation is usually more fragile than using a proper API. Websites can change their interface and break your automation.&lt;/p&gt;

&lt;p&gt;Always check a website's terms and access rules before automating it.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. File and computer automation
&lt;/h1&gt;

&lt;p&gt;You can also automate tasks directly on your computer.&lt;/p&gt;

&lt;p&gt;Python can work with files, folders, CSV files, Excel files, and other data.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Downloaded files -&amp;gt; identify file type -&amp;gt; rename -&amp;gt; move to correct folder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Useful Python libraries include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;os&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pathlib&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shutil&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pandas&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openpyxl&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't need complicated AI for this.&lt;/p&gt;

&lt;p&gt;Sometimes a 30-line script can eliminate hours of repetitive work.&lt;/p&gt;




&lt;h1&gt;
  
  
  Scheduling your automation
&lt;/h1&gt;

&lt;p&gt;An automation isn't very useful if you still have to remember to start it every morning.&lt;/p&gt;

&lt;p&gt;You can schedule your code to run automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;

&lt;p&gt;Use &lt;strong&gt;Task Scheduler&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linux and macOS
&lt;/h3&gt;

&lt;p&gt;You can use &lt;strong&gt;cron&lt;/strong&gt; or other scheduling tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloud
&lt;/h3&gt;

&lt;p&gt;You can run automation using services such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Actions&lt;/li&gt;
&lt;li&gt;AWS Lambda&lt;/li&gt;
&lt;li&gt;Azure Functions&lt;/li&gt;
&lt;li&gt;Google Cloud Functions&lt;/li&gt;
&lt;li&gt;Cloud Run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also use workflow platforms that handle scheduling for you.&lt;/p&gt;

&lt;p&gt;The important concept is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Build it once, then let the system run it repeatedly.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  How to choose your first automation
&lt;/h1&gt;

&lt;p&gt;Don't start by asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What cool automation can I build?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Start with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What repetitive problem do I have?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For one week, pay attention to the things you repeatedly do on your computer or phone.&lt;/p&gt;

&lt;p&gt;Write them down.&lt;/p&gt;

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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Frequency&lt;/th&gt;
&lt;th&gt;Can it be automated?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Copy data from email to spreadsheet&lt;/td&gt;
&lt;td&gt;10/day&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Send daily report&lt;/td&gt;
&lt;td&gt;1/day&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rename downloaded files&lt;/td&gt;
&lt;td&gt;20/day&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decide whether a customer deserves a refund&lt;/td&gt;
&lt;td&gt;2/week&lt;/td&gt;
&lt;td&gt;Maybe, needs rules/human review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Design a new product&lt;/td&gt;
&lt;td&gt;Occasionally&lt;/td&gt;
&lt;td&gt;Not fully&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Look for tasks that are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repetitive&lt;/li&gt;
&lt;li&gt;Predictable&lt;/li&gt;
&lt;li&gt;Rule-based&lt;/li&gt;
&lt;li&gt;Time-consuming&lt;/li&gt;
&lt;li&gt;Prone to human error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are excellent automation candidates.&lt;/p&gt;




&lt;h1&gt;
  
  
  Start with one small win
&lt;/h1&gt;

&lt;p&gt;Don't try to automate your entire business.&lt;/p&gt;

&lt;p&gt;Pick one small problem.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"Whenever I receive an invoice by email, save the attachment to a specific folder."&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Once it works, improve it.&lt;/p&gt;

&lt;p&gt;Maybe you add:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Extract invoice details -&amp;gt; save to database -&amp;gt; notify finance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use AI to extract the invoice number, supplier, amount, and due date.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now you have progressed from a simple automation to an AI-powered workflow.&lt;/p&gt;




&lt;h1&gt;
  
  
  A practical learning path for beginners
&lt;/h1&gt;

&lt;p&gt;If you are completely new, I would learn automation in this order.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Learn the basic concepts
&lt;/h3&gt;

&lt;p&gt;Understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Triggers&lt;/li&gt;
&lt;li&gt;Actions&lt;/li&gt;
&lt;li&gt;Conditions&lt;/li&gt;
&lt;li&gt;Data&lt;/li&gt;
&lt;li&gt;Workflows&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;Webhooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't worry about advanced AI yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Build a no-code automation
&lt;/h3&gt;

&lt;p&gt;Use something like Power Automate, Make, Zapier, or n8n.&lt;/p&gt;

&lt;p&gt;Build something simple.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Form submission -&amp;gt; spreadsheet -&amp;gt; email notification&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 3: Learn APIs
&lt;/h3&gt;

&lt;p&gt;Understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP&lt;/li&gt;
&lt;li&gt;GET&lt;/li&gt;
&lt;li&gt;POST&lt;/li&gt;
&lt;li&gt;PUT/PATCH&lt;/li&gt;
&lt;li&gt;DELETE&lt;/li&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;API keys&lt;/li&gt;
&lt;li&gt;OAuth&lt;/li&gt;
&lt;li&gt;Webhooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where automation starts becoming much more powerful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Learn some Python
&lt;/h3&gt;

&lt;p&gt;You don't need to become a Python expert immediately.&lt;/p&gt;

&lt;p&gt;Learn enough to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read and write files&lt;/li&gt;
&lt;li&gt;Work with JSON&lt;/li&gt;
&lt;li&gt;Make HTTP requests&lt;/li&gt;
&lt;li&gt;Work with APIs&lt;/li&gt;
&lt;li&gt;Process data&lt;/li&gt;
&lt;li&gt;Connect to databases&lt;/li&gt;
&lt;li&gt;Handle errors&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5: Introduce AI
&lt;/h3&gt;

&lt;p&gt;Learn how to use AI for tasks such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Classification&lt;/li&gt;
&lt;li&gt;Summarization&lt;/li&gt;
&lt;li&gt;Data extraction&lt;/li&gt;
&lt;li&gt;Text generation&lt;/li&gt;
&lt;li&gt;Document processing&lt;/li&gt;
&lt;li&gt;Information retrieval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then combine AI with your workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Learn how to deploy and monitor
&lt;/h3&gt;

&lt;p&gt;A real automation needs more than just working code.&lt;/p&gt;

&lt;p&gt;Learn about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;Retries&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Secrets management&lt;/li&gt;
&lt;li&gt;Monitoring&lt;/li&gt;
&lt;li&gt;Scheduling&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what separates a small experiment from a reliable production automation.&lt;/p&gt;




&lt;h1&gt;
  
  
  A simple project you can build today
&lt;/h1&gt;

&lt;p&gt;Here's a beginner-friendly project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automated expense tracker
&lt;/h2&gt;

&lt;p&gt;Imagine you receive payment or expense notifications by email.&lt;/p&gt;

&lt;p&gt;You could build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New email
    |
    v
Extract transaction information
    |
    v
Check transaction type
    |
    v
Save to spreadsheet/database
    |
    v
Send confirmation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later, add AI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New transaction message
        |
        v
AI extracts:
- Amount
- Merchant
- Category
- Date
        |
        v
Save structured data
        |
        v
Generate weekly summary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you are learning automation, APIs, data processing, and AI in one project.&lt;/p&gt;




&lt;h1&gt;
  
  
  The most important lesson
&lt;/h1&gt;

&lt;p&gt;Don't learn automation by memorizing tools.&lt;/p&gt;

&lt;p&gt;Tools will change.&lt;/p&gt;

&lt;p&gt;The concepts will remain.&lt;/p&gt;

&lt;p&gt;Learn to look at a manual process and ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What starts this process?&lt;/p&gt;

&lt;p&gt;What information is available?&lt;/p&gt;

&lt;p&gt;What decisions need to be made?&lt;/p&gt;

&lt;p&gt;What steps are repetitive?&lt;/p&gt;

&lt;p&gt;What can a computer do automatically?&lt;/p&gt;

&lt;p&gt;Where does the process require human judgment?&lt;/p&gt;

&lt;p&gt;Could AI help with the parts that involve understanding unstructured information?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That way of thinking is more valuable than knowing how to use one particular automation platform.&lt;/p&gt;




&lt;h1&gt;
  
  
  Automation is not about removing humans
&lt;/h1&gt;

&lt;p&gt;A common misconception is that automation means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Replace the human."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A better way to think about it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Automate the repetitive parts so humans can focus on the valuable parts.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A human might still approve a payment, review an important customer complaint, or make a business decision.&lt;/p&gt;

&lt;p&gt;The automation simply handles the work around that decision.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Before automation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Employee reads 100 emails -&amp;gt; identifies categories -&amp;gt; copies information -&amp;gt; creates tickets -&amp;gt; notifies teams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After automation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI classifies emails -&amp;gt; automation creates tickets -&amp;gt; relevant teams are notified -&amp;gt; employee reviews the important cases.&lt;/p&gt;

&lt;p&gt;The human is still involved, but their time is being used much more effectively.&lt;/p&gt;




&lt;h1&gt;
  
  
  Where you should start
&lt;/h1&gt;

&lt;p&gt;If you are completely new, don't try to learn everything at once.&lt;/p&gt;

&lt;p&gt;Start with this mental model:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trigger -&amp;gt; Get data -&amp;gt; Process data -&amp;gt; Make a decision -&amp;gt; Take action&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then ask yourself where AI can help.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Trigger:&lt;/strong&gt; Customer sends a message&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get data:&lt;/strong&gt; Retrieve the customer's account information&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Process:&lt;/strong&gt; AI understands the message&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision:&lt;/strong&gt; Determine what the customer needs&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Action:&lt;/strong&gt; Create a ticket, send a response, or escalate to a human&lt;/p&gt;

&lt;p&gt;Once you understand this pattern, you can build surprisingly sophisticated systems.&lt;/p&gt;

&lt;p&gt;And you don't have to start with a complex AI agent.&lt;/p&gt;

&lt;p&gt;Start with one annoying repetitive task.&lt;/p&gt;

&lt;p&gt;Automate it.&lt;/p&gt;

&lt;p&gt;Then make it better.&lt;/p&gt;

&lt;p&gt;That's how you get started with automation.&lt;/p&gt;

</description>
      <category>python</category>
    </item>
    <item>
      <title>MCP vs API: What They Are, How They Work, and When to Use Each</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Tue, 06 Oct 2026 17:11:57 +0000</pubDate>
      <link>https://dev.to/msnmongare/mcp-vs-api-what-they-are-how-they-work-and-when-to-use-each-515j</link>
      <guid>https://dev.to/msnmongare/mcp-vs-api-what-they-are-how-they-work-and-when-to-use-each-515j</guid>
      <description>&lt;p&gt;If you work in backend engineering, integrations, or AI development, you have probably started hearing about &lt;strong&gt;MCP&lt;/strong&gt; alongside something you already know well: &lt;strong&gt;APIs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At first glance, MCP can look like another way of building an API. It is not.&lt;/p&gt;

&lt;p&gt;Both MCP and APIs allow software systems to communicate, but they solve different problems. An API is primarily a &lt;strong&gt;general-purpose interface between software systems&lt;/strong&gt;, while MCP is designed to give &lt;strong&gt;AI applications a standardized way to discover and use tools, resources, and capabilities&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Understanding this distinction is important because MCP does not replace APIs. In many practical systems, &lt;strong&gt;MCP actually sits on top of existing APIs&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an API?
&lt;/h2&gt;

&lt;p&gt;API stands for &lt;strong&gt;Application Programming Interface&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An API defines how one piece of software can interact with another.&lt;/p&gt;

&lt;p&gt;For example, suppose you are building an e-commerce application and need to retrieve a customer's orders.&lt;/p&gt;

&lt;p&gt;Your backend might call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/customers/123/orders
Authorization: Bearer &amp;lt;token&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server could respond:&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;"customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"paid"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API defines things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What endpoint to call&lt;/li&gt;
&lt;li&gt;What HTTP method to use&lt;/li&gt;
&lt;li&gt;What parameters are required&lt;/li&gt;
&lt;li&gt;How authentication works&lt;/li&gt;
&lt;li&gt;What data is returned&lt;/li&gt;
&lt;li&gt;What errors mean&lt;/li&gt;
&lt;li&gt;What operations are available&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives developers a predictable contract for integrating systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  A simple way to think about an API
&lt;/h3&gt;

&lt;p&gt;An API is like a &lt;strong&gt;service counter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You know what services the counter provides, you know how to request them, and you know what kind of response you will receive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your application
       |
       | HTTP request
       v
     API
       |
       v
   Backend system
       |
       v
    Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;APIs are therefore fundamental to modern software architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is MCP?
&lt;/h2&gt;

&lt;p&gt;MCP stands for &lt;strong&gt;Model Context Protocol&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is a protocol designed to standardize how AI applications interact with external &lt;strong&gt;tools, resources, and prompts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of building a custom integration for every AI application, MCP provides a common protocol that an AI client can use to discover and interact with capabilities exposed by an MCP server.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              AI application
                    |
                   MCP
                    |
          +---------+---------+
          |         |         |
        Tools    Resources   Prompts
          |         |         |
       Database    Files     Templates
       API         Docs
       SaaS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, an MCP server might expose tools such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_customer()
create_invoice()
search_transactions()
send_payment()
get_account_balance()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An AI agent can discover these capabilities and decide when to use them.&lt;/p&gt;

&lt;p&gt;This is one of the important differences between MCP and a traditional API.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fundamental difference
&lt;/h2&gt;

&lt;p&gt;The simplest distinction is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;APIs are primarily designed for software-to-software communication. MCP is designed to standardize AI-to-tool interaction.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Consider a payment system.&lt;/p&gt;

&lt;p&gt;You might have an API such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /payments
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A traditional application knows how to call this endpoint because a developer explicitly programmed that integration.&lt;/p&gt;

&lt;p&gt;With MCP, an AI agent could be given a tool such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create_payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with a defined schema:&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;"customer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI application can discover that tool and determine that it should use it based on the user's request.&lt;/p&gt;

&lt;p&gt;So the distinction is not simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API vs MCP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application -&amp;gt; API -&amp;gt; System

AI Agent -&amp;gt; MCP -&amp;gt; Tools/Resources -&amp;gt; Systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in many real systems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI Agent
    |
   MCP
    |
 MCP Server
    |
   API
    |
Backend System
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How a traditional API works
&lt;/h2&gt;

&lt;p&gt;Let's take a simple banking example.&lt;/p&gt;

&lt;p&gt;A mobile application wants to retrieve an account balance.&lt;/p&gt;

&lt;p&gt;The developer might implement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /accounts/123/balance
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API server authenticates the request and returns:&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;"account_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"balance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;125000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"KES"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application already knows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which endpoint to call&lt;/li&gt;
&lt;li&gt;When to call it&lt;/li&gt;
&lt;li&gt;What parameters to provide&lt;/li&gt;
&lt;li&gt;How to interpret the response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The developer wrote that logic.&lt;/p&gt;

&lt;p&gt;The API is therefore a &lt;strong&gt;contract between systems&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How MCP works
&lt;/h2&gt;

&lt;p&gt;MCP introduces another layer.&lt;/p&gt;

&lt;p&gt;An AI application connects to an MCP server.&lt;/p&gt;

&lt;p&gt;The MCP server exposes capabilities that the AI can discover.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MCP Server
|
+-- Tools
|   +-- get_customer
|   +-- search_orders
|   +-- create_invoice
|
+-- Resources
|   +-- customer documentation
|   +-- product catalog
|
+-- Prompts
    +-- customer support prompt
    +-- reporting prompt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI application can discover what is available.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tool:
search_orders

Input:
{
  customer_id: string,
  status: string
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model can then determine:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The user wants to know whether customer 123 has any unpaid orders. I have a tool called &lt;code&gt;search_orders&lt;/code&gt;, so I should use it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It can invoke the tool with structured arguments.&lt;/p&gt;

&lt;p&gt;The MCP server then performs the operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP does not magically replace your backend
&lt;/h2&gt;

&lt;p&gt;This is one of the most important things to understand.&lt;/p&gt;

&lt;p&gt;If you already have a well-designed API, you do not necessarily need to throw it away because you are adopting MCP.&lt;/p&gt;

&lt;p&gt;Instead, MCP can act as an &lt;strong&gt;AI-friendly interface over your existing systems&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 AI Agent
                    |
                   MCP
                    |
              MCP Server
                    |
        +-----------+-----------+
        |           |           |
       REST        SQL        SaaS API
       API       Database       API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose your company already has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /customers/{id}
POST /payments
GET /transactions
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could build MCP tools around those capabilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_customer
create_payment
search_transactions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP server translates the AI's tool invocation into the appropriate backend operation.&lt;/p&gt;

&lt;p&gt;This is similar to building an adapter layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  API vs MCP: A practical comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;API&lt;/th&gt;
&lt;th&gt;MCP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary purpose&lt;/td&gt;
&lt;td&gt;Software integration&lt;/td&gt;
&lt;td&gt;AI-to-tool integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Main consumer&lt;/td&gt;
&lt;td&gt;Applications/developers&lt;/td&gt;
&lt;td&gt;AI models/agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interface&lt;/td&gt;
&lt;td&gt;Endpoints/functions&lt;/td&gt;
&lt;td&gt;Tools/resources/prompts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discovery&lt;/td&gt;
&lt;td&gt;Documentation/specification&lt;/td&gt;
&lt;td&gt;Protocol-based capability discovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical interaction&lt;/td&gt;
&lt;td&gt;Request/response&lt;/td&gt;
&lt;td&gt;AI discovers and invokes capabilities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;td&gt;API keys, OAuth, JWT, etc.&lt;/td&gt;
&lt;td&gt;Depends on implementation and environment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data access&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes, through exposed resources/tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool execution&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI-specific&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replaces APIs?&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Usually no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best use&lt;/td&gt;
&lt;td&gt;Application integration&lt;/td&gt;
&lt;td&gt;Giving AI controlled access to systems&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  APIs are deterministic interfaces
&lt;/h2&gt;

&lt;p&gt;Imagine you have a weather API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /weather?city=Nairobi
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A developer explicitly decides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nairobi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The program knows exactly what it is doing.&lt;/p&gt;

&lt;p&gt;The API does not need to understand natural language.&lt;/p&gt;

&lt;p&gt;It simply receives a valid request and processes it.&lt;/p&gt;

&lt;p&gt;This makes APIs excellent for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mobile applications&lt;/li&gt;
&lt;li&gt;Web applications&lt;/li&gt;
&lt;li&gt;Microservices&lt;/li&gt;
&lt;li&gt;Payment integrations&lt;/li&gt;
&lt;li&gt;Third-party integrations&lt;/li&gt;
&lt;li&gt;Data pipelines&lt;/li&gt;
&lt;li&gt;System-to-system communication&lt;/li&gt;
&lt;li&gt;Event-driven architectures&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MCP introduces model-driven tool selection
&lt;/h2&gt;

&lt;p&gt;Now imagine a user tells an AI assistant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Check my outstanding invoices and send reminders to customers who are overdue."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That could require several operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Find invoices
2. Determine which are overdue
3. Retrieve customer information
4. Generate reminder messages
5. Send messages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI agent could potentially use several MCP tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search_invoices()
get_customer()
send_message()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model decides which tools are relevant based on the task.&lt;/p&gt;

&lt;p&gt;This is where MCP becomes particularly useful.&lt;/p&gt;

&lt;p&gt;The developer does not necessarily have to create a separate hard-coded workflow for every possible natural-language request.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP is especially useful for AI agents
&lt;/h2&gt;

&lt;p&gt;Traditional software generally follows predetermined workflows.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Receive payment
      |
      v
Validate payment
      |
      v
Update database
      |
      v
Send notification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An AI agent may instead operate more dynamically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User request
      |
      v
AI Agent
      |
      +----&amp;gt; Search customer
      |
      +----&amp;gt; Check payment
      |
      +----&amp;gt; Query documentation
      |
      +----&amp;gt; Create response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent can select tools based on context.&lt;/p&gt;

&lt;p&gt;This makes MCP particularly interesting for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI agents&lt;/li&gt;
&lt;li&gt;Coding assistants&lt;/li&gt;
&lt;li&gt;Enterprise copilots&lt;/li&gt;
&lt;li&gt;Customer support agents&lt;/li&gt;
&lt;li&gt;Research agents&lt;/li&gt;
&lt;li&gt;Data analysis agents&lt;/li&gt;
&lt;li&gt;Internal automation&lt;/li&gt;
&lt;li&gt;AI-powered operations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MCP vs API is not really an either/or decision
&lt;/h2&gt;

&lt;p&gt;This is where many discussions about MCP become misleading.&lt;/p&gt;

&lt;p&gt;You don't necessarily choose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MCP OR API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You often use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MCP + APIs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, imagine a Kenyan fintech platform.&lt;/p&gt;

&lt;p&gt;It already has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Payment API
Customer API
Transaction API
Notification API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the company wants an AI operations agent.&lt;/p&gt;

&lt;p&gt;Instead of giving the AI direct database access, you could create an MCP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    AI Agent
                       |
                      MCP
                       |
                MCP Server
                       |
        +--------------+--------------+
        |              |              |
    Payment API    Customer API   Transaction API
        |              |              |
        +--------------+--------------+
                       |
                    Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The APIs remain the core integration layer.&lt;/p&gt;

&lt;p&gt;MCP provides the interface through which the AI agent interacts with those capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you use an API?
&lt;/h2&gt;

&lt;p&gt;Use an API when you need predictable, programmatic integration.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  A mobile application
&lt;/h3&gt;

&lt;p&gt;Your Android or iOS application might communicate with your backend through REST or GraphQL APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  A payment integration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your application
      |
      v
Payment API
      |
      v
Payment provider
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A microservice architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Orders Service
      |
      v
Payments Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A third-party integration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your system
    |
    v
CRM API
    |
    v
CRM platform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are classic API use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you use MCP?
&lt;/h2&gt;

&lt;p&gt;MCP becomes valuable when an AI model needs to interact with external capabilities.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  AI customer support agent
&lt;/h3&gt;

&lt;p&gt;The agent could use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_customer
search_orders
check_payment
create_ticket
send_message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AI data analyst
&lt;/h3&gt;

&lt;p&gt;The agent could use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query_database
get_schema
run_report
export_csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Coding assistant
&lt;/h3&gt;

&lt;p&gt;The agent could interact with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;read_file
search_code
run_tests
create_branch
inspect_logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enterprise AI assistant
&lt;/h3&gt;

&lt;p&gt;The agent could access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SharePoint
Databases
CRM
ERP
Internal APIs
Documentation
File systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP provides a standardized way to expose these capabilities to the AI application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security changes when AI enters the picture
&lt;/h2&gt;

&lt;p&gt;This is an area developers should take seriously.&lt;/p&gt;

&lt;p&gt;With a normal API, the developer controls when the API is called.&lt;/p&gt;

&lt;p&gt;With an AI agent, the model may decide when a tool should be invoked based on the user's request and the context it receives.&lt;/p&gt;

&lt;p&gt;That introduces additional security considerations.&lt;/p&gt;

&lt;p&gt;Suppose you expose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delete_customer()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as an MCP tool.&lt;/p&gt;

&lt;p&gt;You don't want the model to have unrestricted authority to execute destructive operations.&lt;/p&gt;

&lt;p&gt;You need controls around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;li&gt;Input validation&lt;/li&gt;
&lt;li&gt;Tool permissions&lt;/li&gt;
&lt;li&gt;Least privilege&lt;/li&gt;
&lt;li&gt;Audit logging&lt;/li&gt;
&lt;li&gt;Rate limiting&lt;/li&gt;
&lt;li&gt;Human approval&lt;/li&gt;
&lt;li&gt;Sensitive data access&lt;/li&gt;
&lt;li&gt;Destructive operations&lt;/li&gt;
&lt;li&gt;Prompt injection&lt;/li&gt;
&lt;li&gt;Tool misuse&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fact that an operation is exposed through MCP does &lt;strong&gt;not&lt;/strong&gt; make it safe.&lt;/p&gt;

&lt;p&gt;In fact, giving an AI agent access to powerful tools makes authorization even more important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't give an MCP server unnecessary access
&lt;/h2&gt;

&lt;p&gt;Suppose your AI assistant only needs to check transaction status.&lt;/p&gt;

&lt;p&gt;It probably doesn't need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delete_transaction
refund_payment
create_payment
update_customer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A better design is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MCP Server
|
+-- get_transaction
+-- search_transactions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This follows the principle of least privilege.&lt;/p&gt;

&lt;p&gt;The AI should have access to the smallest set of capabilities required to perform its job.&lt;/p&gt;

&lt;p&gt;This is especially important for financial systems, healthcare systems, enterprise systems, and production infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP can provide a better abstraction for AI
&lt;/h2&gt;

&lt;p&gt;Imagine an API exposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /v1/transactions
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with dozens of parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customer_id
account_id
status
start_date
end_date
page
limit
sort
include_metadata
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A developer can read the API documentation and construct the request.&lt;/p&gt;

&lt;p&gt;But an AI agent benefits from a more semantic tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search_transactions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with a clearly defined schema and description.&lt;/p&gt;

&lt;p&gt;For example:&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;"customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"failed"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP layer can hide some of the underlying implementation complexity.&lt;/p&gt;

&lt;p&gt;That makes MCP useful as an &lt;strong&gt;AI-facing abstraction layer&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Think of MCP as a bridge
&lt;/h2&gt;

&lt;p&gt;A useful mental model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Human
                  |
                  v
              AI Agent
                  |
                  v
                 MCP
                  |
        +---------+---------+
        |         |         |
       API       DB       SaaS
        |         |         |
        +---------+---------+
                  |
               Systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API remains valuable.&lt;/p&gt;

&lt;p&gt;The database remains valuable.&lt;/p&gt;

&lt;p&gt;The SaaS integrations remain valuable.&lt;/p&gt;

&lt;p&gt;MCP provides a standardized way for the AI layer to interact with those capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  An example from a real business
&lt;/h2&gt;

&lt;p&gt;Imagine an insurance company.&lt;/p&gt;

&lt;p&gt;It has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claims API
Policy API
Customer API
Payments API
Document repository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The company wants an internal AI claims assistant.&lt;/p&gt;

&lt;p&gt;A traditional application could use APIs directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claims UI
   |
   +--&amp;gt; Claims API
   +--&amp;gt; Policy API
   +--&amp;gt; Customer API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An AI assistant could instead have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claims AI Agent
       |
      MCP
       |
   MCP Server
       |
       +--&amp;gt; get_claim()
       +--&amp;gt; get_policy()
       +--&amp;gt; get_customer()
       +--&amp;gt; search_documents()
       |
       v
Existing enterprise systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now an employee can ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What is the current status of claim 45821 and what documents are still missing?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent can determine which tools it needs, retrieve the information, and formulate the response.&lt;/p&gt;

&lt;h2&gt;
  
  
  What MCP does not solve
&lt;/h2&gt;

&lt;p&gt;MCP is not a replacement for good software architecture.&lt;/p&gt;

&lt;p&gt;It does not automatically solve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;li&gt;Data modeling&lt;/li&gt;
&lt;li&gt;Database design&lt;/li&gt;
&lt;li&gt;API design&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Observability&lt;/li&gt;
&lt;li&gt;Reliability&lt;/li&gt;
&lt;li&gt;Business logic&lt;/li&gt;
&lt;li&gt;Transaction management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You still need to build those properly.&lt;/p&gt;

&lt;p&gt;MCP is a protocol for connecting AI applications to capabilities. It does not eliminate the engineering underneath.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple decision framework
&lt;/h2&gt;

&lt;p&gt;When deciding between MCP and an API, ask:&lt;/p&gt;

&lt;h3&gt;
  
  
  "Who is consuming this interface?"
&lt;/h3&gt;

&lt;p&gt;If the answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Another application&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Use an API.&lt;/p&gt;

&lt;p&gt;If the answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An AI application or agent&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;MCP may be appropriate.&lt;/p&gt;

&lt;p&gt;But if your AI agent needs to interact with an existing backend, you may want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI Agent
   |
  MCP
   |
Existing APIs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than replacing those APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  API first, MCP when AI needs it
&lt;/h2&gt;

&lt;p&gt;For many organizations, a sensible architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Applications
                     |
                     v
                   APIs
                     |
              Business Logic
                     |
              Data / Services


                AI Applications
                     |
                     v
                    MCP
                     |
                     v
                   APIs
                     |
              Business Logic
                     |
              Data / Services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separates concerns.&lt;/p&gt;

&lt;p&gt;Your APIs remain your general integration layer.&lt;/p&gt;

&lt;p&gt;MCP becomes your AI integration layer.&lt;/p&gt;

&lt;p&gt;That architecture also means your existing systems do not have to be redesigned simply because you are introducing AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  The key takeaway
&lt;/h2&gt;

&lt;p&gt;MCP and APIs are not competitors in the way they are sometimes presented.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;APIs answer:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How can software interact with this system?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;MCP answers:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How can an AI application discover and interact with tools, resources, and capabilities?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;If you are building a payment gateway, mobile backend, microservice, SaaS integration, or enterprise integration, you still need APIs.&lt;/p&gt;

&lt;p&gt;If you are building an AI agent that needs to interact with those systems, MCP can provide the standardized interface between the agent and those capabilities.&lt;/p&gt;

&lt;p&gt;The architecture may ultimately look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 User
                   |
                   v
                AI Agent
                   |
                  MCP
                   |
              MCP Server
                   |
             Business Logic
                   |
          +--------+--------+
          |        |        |
         API      DB      Services
          |        |        |
          +--------+--------+
                   |
              Enterprise
                Systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So rather than asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Should I use MCP or an API?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A better question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What system am I integrating, who is consuming the interface, and does an AI agent need to discover and invoke these capabilities?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If it is application-to-application communication, start with an API.&lt;/p&gt;

&lt;p&gt;If it is AI-to-tool interaction, consider MCP.&lt;/p&gt;

&lt;p&gt;And when you already have APIs, &lt;strong&gt;MCP can sit on top of them rather than replacing them.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>mcp</category>
      <category>api</category>
      <category>backend</category>
    </item>
    <item>
      <title>Azure Data Factory vs Apache Airflow: Two Different Ways to Build Data Pipelines</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Fri, 02 Oct 2026 12:35:23 +0000</pubDate>
      <link>https://dev.to/msnmongare/azure-data-factory-vs-apache-airflow-two-different-ways-to-build-data-pipelines-j62</link>
      <guid>https://dev.to/msnmongare/azure-data-factory-vs-apache-airflow-two-different-ways-to-build-data-pipelines-j62</guid>
      <description>&lt;p&gt;When people compare Azure Data Factory (ADF) and Apache Airflow, the conversation often becomes a comparison of features.&lt;/p&gt;

&lt;p&gt;Both can orchestrate data pipelines. Both can call APIs. Both can move data between systems. Both can schedule jobs, monitor executions, and integrate with data platforms.&lt;/p&gt;

&lt;p&gt;But that can be misleading.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ADF and Airflow solve similar problems using fundamentally different approaches.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Azure Data Factory is primarily a &lt;strong&gt;visual, configuration-driven data integration and ETL/ELT service&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Apache Airflow is primarily a &lt;strong&gt;programmatic, code-driven workflow orchestration platform&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Understanding this distinction is more important than simply comparing their feature lists.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, what is Azure Data Factory?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Azure Data Factory (ADF)&lt;/strong&gt; is a cloud-based data integration service from Microsoft Azure.&lt;/p&gt;

&lt;p&gt;Its main purpose is to help you build pipelines that move and transform data between different systems.&lt;/p&gt;

&lt;p&gt;Instead of writing an entire pipeline as a Python program, you can construct it using visual activities.&lt;/p&gt;

&lt;p&gt;For example, an ADF pipeline might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Get Configuration
       |
       v
Get Access Token
       |
       v
Call API
       |
       v
Store JSON in Azure Data Lake
       |
       v
Transform / Copy Data
       |
       v
Load Azure SQL / Synapse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each box represents an activity configured through the ADF interface.&lt;/p&gt;

&lt;p&gt;You can configure things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URLs&lt;/li&gt;
&lt;li&gt;HTTP methods&lt;/li&gt;
&lt;li&gt;Headers&lt;/li&gt;
&lt;li&gt;Parameters&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Source and destination datasets&lt;/li&gt;
&lt;li&gt;Column mappings&lt;/li&gt;
&lt;li&gt;Retry policies&lt;/li&gt;
&lt;li&gt;Dependencies&lt;/li&gt;
&lt;li&gt;Expressions&lt;/li&gt;
&lt;li&gt;Conditional logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ADF also integrates with other Azure services such as Azure Key Vault, Azure Data Lake Storage, Azure SQL, Azure Synapse and Azure Monitor.&lt;/p&gt;

&lt;p&gt;The important idea is that &lt;strong&gt;you primarily describe what should happen through configuration and visual activities rather than implementing the entire workflow in application code.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Apache Airflow?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apache Airflow&lt;/strong&gt; is an open-source platform for programmatically authoring, scheduling and monitoring workflows.&lt;/p&gt;

&lt;p&gt;Instead of building a pipeline primarily through a visual interface, you define it in code.&lt;/p&gt;

&lt;p&gt;An Airflow workflow is usually represented as a &lt;strong&gt;DAG - Directed Acyclic Graph&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;airflow&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DAG&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;airflow.operators.python&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PythonOperator&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;DAG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;dag_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;zoho_pipeline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;schedule&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@daily&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;dag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;extract_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PythonOperator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extract_data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;python_callable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;extract_from_zoho&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;transform_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PythonOperator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;transform_data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;python_callable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;transform_data&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;load_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PythonOperator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;load_data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;python_callable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;load_to_database&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;extract_data&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;transform_data&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;load_data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code defines the workflow and its dependencies.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;extract_data
      |
      v
transform_data
      |
      v
load_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Airflow does not primarily exist to perform every data transformation itself. Its core strength is &lt;strong&gt;orchestration&lt;/strong&gt; - coordinating tasks and systems.&lt;/p&gt;

&lt;p&gt;Those tasks could involve Python, SQL, dbt, Spark, APIs, cloud services, containers or other external systems.&lt;/p&gt;




&lt;h1&gt;
  
  
  ADF vs Airflow: The Core Difference
&lt;/h1&gt;

&lt;p&gt;The simplest way to understand the difference is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ADF asks you to configure a data pipeline. Airflow asks you to program a workflow.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This distinction affects almost everything else.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;Azure Data Factory&lt;/th&gt;
&lt;th&gt;Apache Airflow&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Core paradigm&lt;/td&gt;
&lt;td&gt;Visual, configuration-driven&lt;/td&gt;
&lt;td&gt;Programmatic, code-driven&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary interface&lt;/td&gt;
&lt;td&gt;Web UI&lt;/td&gt;
&lt;td&gt;Python code + UI for monitoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workflow definition&lt;/td&gt;
&lt;td&gt;Pipelines and activities&lt;/td&gt;
&lt;td&gt;Python DAGs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API integration&lt;/td&gt;
&lt;td&gt;Activities, REST connectors, datasets&lt;/td&gt;
&lt;td&gt;Python libraries, operators, hooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transformations&lt;/td&gt;
&lt;td&gt;Mapping Data Flows, Copy Activity, SQL, etc.&lt;/td&gt;
&lt;td&gt;Python, SQL, dbt, Spark and external tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Version control&lt;/td&gt;
&lt;td&gt;Possible through Git integration&lt;/td&gt;
&lt;td&gt;Natural fit because DAGs are code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure&lt;/td&gt;
&lt;td&gt;Microsoft-managed service&lt;/td&gt;
&lt;td&gt;You manage or use a managed Airflow service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure integration&lt;/td&gt;
&lt;td&gt;Deep native integration&lt;/td&gt;
&lt;td&gt;Strong, but usually through operators/providers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-cloud&lt;/td&gt;
&lt;td&gt;Possible&lt;/td&gt;
&lt;td&gt;Strong fit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom Python logic&lt;/td&gt;
&lt;td&gt;Possible, but often indirect&lt;/td&gt;
&lt;td&gt;Native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;td&gt;Azure portal&lt;/td&gt;
&lt;td&gt;Airflow UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaling&lt;/td&gt;
&lt;td&gt;Managed by Azure services&lt;/td&gt;
&lt;td&gt;Depends on Airflow deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintenance&lt;/td&gt;
&lt;td&gt;Low infrastructure management&lt;/td&gt;
&lt;td&gt;Higher infrastructure responsibility&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Neither approach is universally "better". They optimize for different engineering models.&lt;/p&gt;

&lt;h1&gt;
  
  
  Example: Connecting to the Zoho API
&lt;/h1&gt;

&lt;p&gt;Suppose you need to extract data from Zoho.&lt;/p&gt;

&lt;p&gt;The API requires:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Obtaining an access token&lt;/li&gt;
&lt;li&gt;Calling an API endpoint&lt;/li&gt;
&lt;li&gt;Passing authentication headers&lt;/li&gt;
&lt;li&gt;Handling pagination&lt;/li&gt;
&lt;li&gt;Saving the response&lt;/li&gt;
&lt;li&gt;Transforming the JSON&lt;/li&gt;
&lt;li&gt;Loading the data into a warehouse&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  In ADF
&lt;/h3&gt;

&lt;p&gt;You can construct this visually.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Web Activity
    |
    | Get OAuth token
    v
Set Variable
    |
    | Store token
    v
Web Activity / Copy Activity
    |
    | Call Zoho API
    v
Azure Data Lake
    |
    v
Copy Activity
    |
    v
Azure SQL / Synapse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Credentials such as the Zoho client secret should be stored in a secure service such as Azure Key Vault rather than hardcoded in the pipeline.&lt;/p&gt;

&lt;p&gt;ADF allows you to configure URLs, headers, parameters, expressions and activity dependencies through its interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  In Airflow
&lt;/h3&gt;

&lt;p&gt;The same workflow might be implemented in Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DAG
 |
 +-- Get Zoho Token
 |
 +-- Extract Zoho Data
 |
 +-- Transform JSON
 |
 +-- Load Warehouse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API interaction could use Python's &lt;code&gt;requests&lt;/code&gt; library or an appropriate Airflow provider/operator.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;api_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Zoho-oauthtoken &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference becomes more noticeable when the API becomes complicated.&lt;/p&gt;

&lt;p&gt;If you need custom retry logic, unusual pagination, token refresh behavior or complicated response processing, Python gives you considerably more freedom.&lt;/p&gt;

&lt;h1&gt;
  
  
  What About JSON Transformations?
&lt;/h1&gt;

&lt;p&gt;APIs rarely return perfectly flat data.&lt;/p&gt;

&lt;p&gt;You might receive:&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;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"activities"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"call"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-30"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may need to flatten:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data
  -&amp;gt; customer
       -&amp;gt; activities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ADF approach
&lt;/h3&gt;

&lt;p&gt;ADF can handle many transformations through Copy Activity mappings and Mapping Data Flows.&lt;/p&gt;

&lt;p&gt;You can configure mappings and expressions through the UI.&lt;/p&gt;

&lt;p&gt;This works well when the transformation can be expressed using ADF's available activities and expressions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Airflow approach
&lt;/h3&gt;

&lt;p&gt;With Airflow, you can process the response using Python.&lt;/p&gt;

&lt;p&gt;For example, libraries such as Pandas can help normalize nested JSON:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;json_normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then apply arbitrary Python logic before loading the result.&lt;/p&gt;

&lt;p&gt;This illustrates a broader difference:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ADF gives you configurable transformation capabilities. Airflow gives you a programming environment from which you can call virtually any transformation tool.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Where Does the Processing Happen?
&lt;/h1&gt;

&lt;p&gt;Another important distinction is execution architecture.&lt;/p&gt;

&lt;p&gt;With ADF, data movement and transformation can be executed through Azure Integration Runtime or other configured compute resources.&lt;/p&gt;

&lt;p&gt;You generally do not manage the underlying servers yourself.&lt;/p&gt;

&lt;p&gt;Airflow, on the other hand, executes tasks through its workers or connected execution environments.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Airflow Scheduler
       |
       v
Airflow Worker
       |
       +-- Python
       +-- SQL
       +-- dbt
       +-- Spark
       +-- API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives engineers considerable control, but it also introduces infrastructure considerations.&lt;/p&gt;

&lt;p&gt;If your Python task loads a very large dataset into memory, for example, the worker's resources become relevant.&lt;/p&gt;

&lt;p&gt;With Airflow, you therefore need to think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Worker sizing&lt;/li&gt;
&lt;li&gt;Concurrency&lt;/li&gt;
&lt;li&gt;Memory&lt;/li&gt;
&lt;li&gt;CPU&lt;/li&gt;
&lt;li&gt;Queues&lt;/li&gt;
&lt;li&gt;Executors&lt;/li&gt;
&lt;li&gt;Containers&lt;/li&gt;
&lt;li&gt;Kubernetes&lt;/li&gt;
&lt;li&gt;Task isolation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That operational responsibility is one of the biggest differences between the two platforms.&lt;/p&gt;

&lt;h1&gt;
  
  
  ADF: When Does It Make Sense?
&lt;/h1&gt;

&lt;p&gt;ADF is particularly attractive when your environment is heavily invested in Azure.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API
 |
 v
ADF
 |
 v
Azure Data Lake
 |
 v
ADF / Transformation
 |
 v
Azure SQL / Synapse / Fabric
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ecosystem fits together naturally.&lt;/p&gt;

&lt;p&gt;ADF can also be a good choice when your team prefers visual development.&lt;/p&gt;

&lt;p&gt;A team consisting primarily of SQL developers, analysts or database professionals may find it easier to understand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Activity A
    |
    v
Activity B
    |
    v
Activity C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;than a Python-based orchestration framework.&lt;/p&gt;

&lt;p&gt;ADF also removes much of the infrastructure burden.&lt;/p&gt;

&lt;p&gt;You do not have to build and maintain an Airflow cluster just to execute your pipelines.&lt;/p&gt;

&lt;h1&gt;
  
  
  Airflow: When Does It Make Sense?
&lt;/h1&gt;

&lt;p&gt;Airflow becomes particularly useful when your organization wants workflows to behave more like software.&lt;/p&gt;

&lt;p&gt;Your pipeline is code.&lt;/p&gt;

&lt;p&gt;Therefore you can naturally apply software engineering practices such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Branching&lt;/li&gt;
&lt;li&gt;Pull requests&lt;/li&gt;
&lt;li&gt;Code reviews&lt;/li&gt;
&lt;li&gt;Automated testing&lt;/li&gt;
&lt;li&gt;CI/CD&lt;/li&gt;
&lt;li&gt;Reusable Python functions&lt;/li&gt;
&lt;li&gt;Package management&lt;/li&gt;
&lt;li&gt;Code quality checks&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Git Repository
      |
      v
Pull Request
      |
      v
Code Review
      |
      v
CI/CD
      |
      v
Airflow
      |
      v
Production DAGs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Airflow is also useful in environments that are not exclusively Azure.&lt;/p&gt;

&lt;p&gt;You could have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Airflow
  |
  +-- Azure
  +-- AWS
  +-- GCP
  +-- Snowflake
  +-- Databricks
  +-- PostgreSQL
  +-- APIs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it attractive for organizations with heterogeneous or multi-cloud data platforms.&lt;/p&gt;

&lt;h1&gt;
  
  
  What About Complex Pipelines?
&lt;/h1&gt;

&lt;p&gt;Imagine a Zoho API that requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple authentication steps&lt;/li&gt;
&lt;li&gt;Token refresh&lt;/li&gt;
&lt;li&gt;Cursor-based pagination&lt;/li&gt;
&lt;li&gt;Custom retry logic&lt;/li&gt;
&lt;li&gt;Rate-limit handling&lt;/li&gt;
&lt;li&gt;Nested JSON processing&lt;/li&gt;
&lt;li&gt;Data validation&lt;/li&gt;
&lt;li&gt;Custom error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In ADF, these requirements can sometimes be implemented using activities, expressions, variables, loops and conditions.&lt;/p&gt;

&lt;p&gt;But the pipeline can become increasingly configuration-heavy.&lt;/p&gt;

&lt;p&gt;In Airflow, you can implement the logic directly in Python.&lt;/p&gt;

&lt;p&gt;That might look conceptually like:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_zoho_data&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_token&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;has_next_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the strongest arguments for a code-based orchestrator.&lt;/p&gt;

&lt;p&gt;When workflow logic becomes software, treating it as software can make the implementation easier to reason about.&lt;/p&gt;

&lt;h1&gt;
  
  
  But Airflow Is Not Automatically Better for Everything
&lt;/h1&gt;

&lt;p&gt;There is an important misconception to avoid.&lt;/p&gt;

&lt;p&gt;Using Python does not automatically make a pipeline better.&lt;/p&gt;

&lt;p&gt;A poorly designed Airflow deployment can introduce significant complexity.&lt;/p&gt;

&lt;p&gt;You now have to think about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Airflow Scheduler
Airflow Workers
Metadata Database
Executor
DAG Deployment
Secrets
Logs
Monitoring
Scaling
Upgrades
Networking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With ADF, much of this infrastructure is abstracted away.&lt;/p&gt;

&lt;p&gt;Therefore, the question should not simply be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can Airflow do this?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It almost certainly can.&lt;/p&gt;

&lt;p&gt;The better question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Does the additional flexibility justify the additional engineering and operational responsibility?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  A Practical Decision Framework
&lt;/h1&gt;

&lt;p&gt;Think about the pipeline and the team building it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose ADF when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Your data platform is primarily Azure&lt;/li&gt;
&lt;li&gt;Your destination is Azure SQL, Synapse, Fabric or Azure Data Lake&lt;/li&gt;
&lt;li&gt;You want a managed service&lt;/li&gt;
&lt;li&gt;Visual pipeline development is valuable&lt;/li&gt;
&lt;li&gt;Most transformations can be handled through existing ADF capabilities&lt;/li&gt;
&lt;li&gt;Your team is comfortable with configuration and SQL&lt;/li&gt;
&lt;li&gt;You want minimal infrastructure management&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Consider Airflow when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Your workflows require substantial custom Python logic&lt;/li&gt;
&lt;li&gt;You operate across multiple clouds or platforms&lt;/li&gt;
&lt;li&gt;Your data engineers are comfortable with Python&lt;/li&gt;
&lt;li&gt;Git-based workflow development is important&lt;/li&gt;
&lt;li&gt;You need complex orchestration&lt;/li&gt;
&lt;li&gt;You need to integrate many different processing technologies&lt;/li&gt;
&lt;li&gt;You want workflows managed using software engineering practices&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  The Most Important Distinction
&lt;/h1&gt;

&lt;p&gt;ADF and Airflow can both orchestrate a pipeline such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API
 |
 v
Extract
 |
 v
Transform
 |
 v
Load
 |
 v
Data Warehouse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But they approach that pipeline differently.&lt;/p&gt;

&lt;p&gt;ADF is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Configure the pipeline
        |
        v
Microsoft manages the platform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Airflow is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write the workflow
        |
        v
Deploy and operate the orchestrator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That difference becomes increasingly important as your data platform grows.&lt;/p&gt;

&lt;p&gt;If your primary goal is Azure-native data integration with minimal infrastructure management, ADF provides a natural model.&lt;/p&gt;

&lt;p&gt;If your primary goal is flexible, code-first workflow orchestration across different systems, Airflow provides a different model.&lt;/p&gt;

&lt;p&gt;Neither tool eliminates the need for good data engineering.&lt;/p&gt;

&lt;p&gt;You still need to think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Secrets management&lt;/li&gt;
&lt;li&gt;Idempotency&lt;/li&gt;
&lt;li&gt;Retries&lt;/li&gt;
&lt;li&gt;Rate limits&lt;/li&gt;
&lt;li&gt;Data quality&lt;/li&gt;
&lt;li&gt;Observability&lt;/li&gt;
&lt;li&gt;Schema changes&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;Incremental loading&lt;/li&gt;
&lt;li&gt;Backfills&lt;/li&gt;
&lt;li&gt;Dependency management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The orchestration tool is only one part of the architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real decision is not simply ADF vs Airflow. It is configuration-driven orchestration vs code-driven orchestration, and which model fits your team's skills, infrastructure and operational requirements.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>airflow</category>
      <category>python</category>
    </item>
    <item>
      <title>Stop Giving AI Coding Agents Your Passwords: A Practical Guide to Secure Credentials</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Fri, 25 Sep 2026 19:31:56 +0000</pubDate>
      <link>https://dev.to/msnmongare/stop-giving-ai-coding-agents-your-passwords-a-practical-guide-to-secure-credentials-59ee</link>
      <guid>https://dev.to/msnmongare/stop-giving-ai-coding-agents-your-passwords-a-practical-guide-to-secure-credentials-59ee</guid>
      <description>&lt;p&gt;AI coding agents such as Cursor, Claude Code, GitHub Copilot and other agentic development tools are changing how developers build and deploy software.&lt;/p&gt;

&lt;p&gt;They can read your code, modify files, run terminal commands, execute tests and, depending on how they are configured, interact with your servers and deployment infrastructure.&lt;/p&gt;

&lt;p&gt;That power is useful - but it also introduces a security problem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you give an AI coding agent enough access to deploy and troubleshoot your application without giving it the keys to your entire infrastructure?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer is not simply "put your password in a &lt;code&gt;.env&lt;/code&gt; file."&lt;/p&gt;

&lt;p&gt;The better approach is to use &lt;strong&gt;least privilege, scoped credentials, SSH keys, CI/CD secrets and separate deployment accounts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is a practical approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Never Paste Your VPS or cPanel Password Into an AI Chat
&lt;/h2&gt;

&lt;p&gt;This should be your first rule.&lt;/p&gt;

&lt;p&gt;Avoid prompts like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;My VPS password is MySuperSecretPassword123.

SSH into the server and deploy my application.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cPanel username: myuser
cPanel password: MyPassword123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if you trust the AI tool, you are unnecessarily exposing a credential through a conversation.&lt;/p&gt;

&lt;p&gt;That credential could potentially appear in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chat history&lt;/li&gt;
&lt;li&gt;Terminal output&lt;/li&gt;
&lt;li&gt;Agent logs&lt;/li&gt;
&lt;li&gt;Debug output&lt;/li&gt;
&lt;li&gt;Screenshots&lt;/li&gt;
&lt;li&gt;Project files&lt;/li&gt;
&lt;li&gt;Shell history&lt;/li&gt;
&lt;li&gt;Deployment logs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More importantly, you are giving the AI agent a secret that may provide far more access than the task actually requires.&lt;/p&gt;

&lt;p&gt;Instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I give Cursor my server password?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"How do I let Cursor perform this task with the minimum access required?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That change in mindset is the foundation of secure AI-assisted development.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Use Environment Variables - But Understand Their Limitation
&lt;/h2&gt;

&lt;p&gt;For local development and deployment scripts, environment variables are much better than hardcoding credentials into your application.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPANEL_FTP_HOST=ftp.example.com
CPANEL_FTP_USER=my_deployment_user
CPANEL_FTP_PASS=your_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your deployment script can then read these values.&lt;/p&gt;

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

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

&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CPANEL_FTP_HOST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CPANEL_FTP_USER&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CPANEL_FTP_PASS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And make sure &lt;code&gt;.env&lt;/code&gt; is ignored by Git:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.env
.env.*
!.env.example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can safely commit a template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPANEL_FTP_HOST=
CPANEL_FTP_USER=
CPANEL_FTP_PASS=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  But here is the important part
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;.env&lt;/code&gt; protects your secrets from being committed to Git. It does not necessarily protect them from an AI coding agent.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If Cursor can read your project directory, it may be able to read &lt;code&gt;.env&lt;/code&gt; too.&lt;/p&gt;

&lt;p&gt;Therefore, don't think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"It is in &lt;code&gt;.env&lt;/code&gt;, so the AI cannot see it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The secret isn't in my source code or Git history, but I still need to control who and what can access the environment."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Prefer SSH Keys Over Password Authentication
&lt;/h2&gt;

&lt;p&gt;For VPS access, SSH keys are generally preferable to passwords.&lt;/p&gt;

&lt;p&gt;Generate an Ed25519 key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will typically have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.ssh/id_ed25519
~/.ssh/id_ed25519.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The public key goes to the server.&lt;/p&gt;

&lt;p&gt;The private key stays on your machine.&lt;/p&gt;

&lt;p&gt;Never share the private key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id_ed25519
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The public key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id_ed25519.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is the one intended to be installed on the server.&lt;/p&gt;

&lt;p&gt;You can then connect using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh deploy@your-server.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This eliminates the need to paste a server password into an AI conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  But there is another important issue
&lt;/h3&gt;

&lt;p&gt;An SSH key is only as safe as the account behind it.&lt;/p&gt;

&lt;p&gt;If your key connects as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you have potentially given the AI agent full control over the server.&lt;/p&gt;

&lt;p&gt;That is not much better than giving it the root password.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Create a Dedicated Deployment User
&lt;/h2&gt;

&lt;p&gt;Instead of giving an AI agent root access, create a dedicated user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Give that user access only to what it needs.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/www/myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than the entire server.&lt;/p&gt;

&lt;p&gt;Your architecture becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI Agent
   |
   v
SSH Key
   |
   v
deploy user
   |
   v
/var/www/myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI Agent
   |
   v
root credentials
   |
   v
Entire VPS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the principle of &lt;strong&gt;least privilege&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If the deployment credential is compromised, the potential damage is limited.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. For cPanel, Create a Dedicated Deployment Account
&lt;/h2&gt;

&lt;p&gt;The same principle applies to cPanel.&lt;/p&gt;

&lt;p&gt;Your main cPanel account may have access to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Websites&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Email&lt;/li&gt;
&lt;li&gt;DNS&lt;/li&gt;
&lt;li&gt;FTP&lt;/li&gt;
&lt;li&gt;SSL&lt;/li&gt;
&lt;li&gt;Cron jobs&lt;/li&gt;
&lt;li&gt;Backups&lt;/li&gt;
&lt;li&gt;File Manager&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is usually no reason for a deployment script to have access to everything.&lt;/p&gt;

&lt;p&gt;Instead, create a dedicated FTP/SFTP account for the application.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Username:
myapp-deploy

Directory:
/public_html/my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the deployment credential is associated with the application rather than your entire hosting account.&lt;/p&gt;

&lt;p&gt;If the credential is compromised, the attacker does not automatically get your entire cPanel account.&lt;/p&gt;

&lt;p&gt;Where supported, prefer secure protocols such as &lt;strong&gt;SFTP or SSH&lt;/strong&gt; over plain FTP.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Separate Development, Staging and Production Credentials
&lt;/h2&gt;

&lt;p&gt;Don't use the same credentials everywhere.&lt;/p&gt;

&lt;p&gt;Avoid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Development -&amp;gt; Production credentials
Staging     -&amp;gt; Production credentials
Production  -&amp;gt; Production credentials
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Development
   |
   +-- Development credentials

Staging
   |
   +-- Staging credentials

Production
   |
   +-- Production credentials
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This becomes especially important when working with AI agents.&lt;/p&gt;

&lt;p&gt;Give your development environment access to test credentials whenever possible.&lt;/p&gt;

&lt;p&gt;For example, if you are integrating a payment API, use sandbox credentials during development instead of your live production secret.&lt;/p&gt;

&lt;p&gt;The same principle applies to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Cloud accounts&lt;/li&gt;
&lt;li&gt;SSH&lt;/li&gt;
&lt;li&gt;Payment APIs&lt;/li&gt;
&lt;li&gt;Email providers&lt;/li&gt;
&lt;li&gt;Third-party APIs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Keep Production Secrets Out of the AI Agent Where Possible
&lt;/h2&gt;

&lt;p&gt;For production deployments, a better architecture is to let the AI agent work on the code while your CI/CD system handles the production credentials.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cursor
   |
   | git push
   v
GitHub
   |
   v
CI/CD
   |
   | Deployment secrets
   v
Production VPS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your GitHub repository contains the code and deployment workflow, but not the actual production password.&lt;/p&gt;

&lt;p&gt;Secrets can be stored in your CI/CD platform's secret store.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEPLOY_HOST
DEPLOY_USER
DEPLOY_SSH_KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow uses those values during deployment without putting them directly into the repository.&lt;/p&gt;

&lt;p&gt;This creates a useful separation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI agent -&amp;gt; code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CI/CD -&amp;gt; production deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is often safer than allowing the AI agent to directly administer production.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Give AI Agents the Minimum Access They Need
&lt;/h2&gt;

&lt;p&gt;Before giving an AI agent access to anything, ask:&lt;/p&gt;

&lt;h3&gt;
  
  
  What does it need to do?
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deploy my application.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What does it need to access?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/www/myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What permissions does it need?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read + write application files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How long does it need access?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Only during deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create credentials around those requirements.&lt;/p&gt;

&lt;p&gt;Don't start with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Here is my root password. Figure it out."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Start with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This deployment user can only modify this application's directory."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. Watch Your Terminal Output
&lt;/h2&gt;

&lt;p&gt;Credentials can leak even when you don't explicitly paste them into a chat.&lt;/p&gt;

&lt;p&gt;Avoid commands such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$CPANEL_PASSWORD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;env&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if your environment contains secrets.&lt;/p&gt;

&lt;p&gt;Also be careful with shell debugging such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because commands containing sensitive values may appear in terminal or CI/CD logs.&lt;/p&gt;

&lt;p&gt;Your rule should be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Secrets should not appear in source code, terminal output, application logs or CI/CD logs.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. What If You Already Shared a Credential?
&lt;/h2&gt;

&lt;p&gt;If you have already pasted a production password, API key or private key into an AI conversation, don't simply delete the message and assume the problem is solved.&lt;/p&gt;

&lt;p&gt;Treat the credential as potentially exposed.&lt;/p&gt;

&lt;p&gt;Rotate it.&lt;/p&gt;

&lt;p&gt;A simple response procedure is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Identify the exposed credential
2. Revoke it
3. Generate a replacement
4. Update the application or deployment system
5. Review authentication and server logs
6. Check for suspicious activity
7. Review how the credential was exposed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For an SSH key, generate a replacement key and remove the old public key from the server.&lt;/p&gt;

&lt;p&gt;For an API key, revoke the old key and generate a new one.&lt;/p&gt;

&lt;p&gt;For a password, change it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Credential rotation is more important than simply deleting the leaked secret from the conversation or code.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  A Practical Secure Setup
&lt;/h1&gt;

&lt;p&gt;For a small VPS or SaaS project, you don't need a complicated enterprise security architecture.&lt;/p&gt;

&lt;p&gt;A practical setup could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                  +----------------+
                  |  Cursor / AI   |
                  |     Agent      |
                  +-------+--------+
                          |
                          v
                  +----------------+
                  |  Source Code   |
                  +-------+--------+
                          |
                       Git Push
                          |
                          v
                  +----------------+
                  |    GitHub      |
                  +-------+--------+
                          |
                          v
                  +----------------+
                  | CI/CD + Secrets|
                  +-------+--------+
                          |
                     SSH / SFTP
                          |
                          v
                  +----------------+
                  | Deploy User    |
                  +-------+--------+
                          |
                          v
                  +----------------+
                  | Application    |
                  | Directory      |
                  +----------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI agent can help you write, test and prepare the application.&lt;/p&gt;

&lt;p&gt;The deployment system handles the production credentials.&lt;/p&gt;

&lt;p&gt;The deployment account has only the permissions required to deploy the application.&lt;/p&gt;




&lt;h1&gt;
  
  
  Security Checklist
&lt;/h1&gt;

&lt;p&gt;Before giving an AI coding agent access to your infrastructure, check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] I am not pasting my master password into an AI chat.&lt;/li&gt;
&lt;li&gt;[ ] Production secrets are not committed to Git.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;.env&lt;/code&gt; is included in &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] I understand that &lt;code&gt;.env&lt;/code&gt; can still be read by an agent with filesystem access.&lt;/li&gt;
&lt;li&gt;[ ] I use SSH keys where practical.&lt;/li&gt;
&lt;li&gt;[ ] Production uses a dedicated deployment user.&lt;/li&gt;
&lt;li&gt;[ ] The deployment user does not have unnecessary root access.&lt;/li&gt;
&lt;li&gt;[ ] cPanel credentials are scoped to the application.&lt;/li&gt;
&lt;li&gt;[ ] Development, staging and production credentials are separate.&lt;/li&gt;
&lt;li&gt;[ ] Production secrets are stored in CI/CD or a secret manager where appropriate.&lt;/li&gt;
&lt;li&gt;[ ] Database users have only the permissions they need.&lt;/li&gt;
&lt;li&gt;[ ] Secrets do not appear in terminal or CI/CD logs.&lt;/li&gt;
&lt;li&gt;[ ] I can quickly revoke and rotate credentials.&lt;/li&gt;
&lt;li&gt;[ ] Destructive production operations require appropriate human approval.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Final Thought
&lt;/h1&gt;

&lt;p&gt;AI coding agents are becoming increasingly capable of interacting with real infrastructure.&lt;/p&gt;

&lt;p&gt;The goal should not be to prevent them from doing useful work.&lt;/p&gt;

&lt;p&gt;The goal is to &lt;strong&gt;limit the damage they can cause if something goes wrong&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Don't ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How can I give Cursor my VPS password?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"How can I allow Cursor to perform this task without giving it unnecessary access to my infrastructure?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Use environment variables to keep secrets out of source code, SSH keys instead of passwords where practical, dedicated deployment users instead of root, scoped cPanel accounts instead of master credentials, and CI/CD or secret managers for production secrets.&lt;/p&gt;

&lt;p&gt;The safest credential is not simply the one that is hidden.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It is the one that has the least power necessary to get the job done.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>learning</category>
      <category>beginners</category>
      <category>security</category>
      <category>agents</category>
    </item>
    <item>
      <title>A Beginner's Guide to Learning RPA: Where to Start and What to Learn</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Thu, 24 Sep 2026 11:43:38 +0000</pubDate>
      <link>https://dev.to/msnmongare/a-beginners-guide-to-learning-rpa-where-to-start-and-what-to-learn-5cj4</link>
      <guid>https://dev.to/msnmongare/a-beginners-guide-to-learning-rpa-where-to-start-and-what-to-learn-5cj4</guid>
      <description>&lt;p&gt;Robotic Process Automation, commonly known as RPA, is an area of technology that focuses on using software robots to automate repetitive, rule-based tasks that people normally perform on computers.&lt;/p&gt;

&lt;p&gt;If you have ever copied information from an email into Excel, downloaded files from a website, entered data into another system, or generated and sent the same report every day, you have probably encountered a process that could potentially be automated with RPA.&lt;/p&gt;

&lt;p&gt;The good news is that you do not need to be an advanced programmer to start learning RPA.&lt;/p&gt;

&lt;p&gt;You can begin with visual automation tools and gradually learn programming, APIs, databases, cloud services and AI as you become more advanced.&lt;/p&gt;

&lt;p&gt;This guide explains a practical path for someone starting from zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is RPA?
&lt;/h2&gt;

&lt;p&gt;Imagine an employee receives an email containing an Excel file every morning.&lt;/p&gt;

&lt;p&gt;They have to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the email.&lt;/li&gt;
&lt;li&gt;Download the Excel file.&lt;/li&gt;
&lt;li&gt;Read the information.&lt;/li&gt;
&lt;li&gt;Open another application.&lt;/li&gt;
&lt;li&gt;Enter the information.&lt;/li&gt;
&lt;li&gt;Save the changes.&lt;/li&gt;
&lt;li&gt;Generate a report.&lt;/li&gt;
&lt;li&gt;Send the report to their manager.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If these steps happen repeatedly and follow predictable rules, an RPA bot can potentially perform them automatically.&lt;/p&gt;

&lt;p&gt;A simple RPA workflow could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Email received
      ↓
Download attachment
      ↓
Read Excel file
      ↓
Validate information
      ↓
Open business application
      ↓
Enter data
      ↓
Generate report
      ↓
Send email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal of RPA is not simply to replace people.&lt;/p&gt;

&lt;p&gt;It is to automate repetitive work so that people can spend more time on tasks that require judgment, communication, creativity and decision-making.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes a good RPA process?
&lt;/h2&gt;

&lt;p&gt;Not every process should be automated.&lt;/p&gt;

&lt;p&gt;RPA works particularly well when a process is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repetitive&lt;/li&gt;
&lt;li&gt;Rule-based&lt;/li&gt;
&lt;li&gt;Predictable&lt;/li&gt;
&lt;li&gt;High-volume&lt;/li&gt;
&lt;li&gt;Time-consuming&lt;/li&gt;
&lt;li&gt;Based on structured data&lt;/li&gt;
&lt;li&gt;Performed using existing computer applications&lt;/li&gt;
&lt;/ul&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Every morning, download a report from a website, process it, update an Excel spreadsheet and email the results.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a good candidate for RPA.&lt;/p&gt;

&lt;p&gt;A process such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Decide whether a complex customer complaint deserves compensation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;may require human judgment and may not be suitable for traditional RPA alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do I need to know programming?
&lt;/h2&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;Many RPA platforms provide visual interfaces where you build workflows by dragging and configuring activities.&lt;/p&gt;

&lt;p&gt;However, learning programming will give you a significant advantage as you become more advanced.&lt;/p&gt;

&lt;p&gt;Useful programming skills include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;SQL&lt;/li&gt;
&lt;li&gt;REST APIs&lt;/li&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;li&gt;Regular expressions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You do not need to master all of these before starting.&lt;/p&gt;

&lt;p&gt;You can learn them gradually as your automation projects become more complex.&lt;/p&gt;

&lt;h1&gt;
  
  
  The main RPA tools to learn
&lt;/h1&gt;

&lt;p&gt;There are many RPA platforms, but beginners do not need to learn all of them.&lt;/p&gt;

&lt;p&gt;I recommend starting with two major tools:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;a href="https://www.microsoft.com/en-us/power-platform/products/power-automate" rel="noopener noreferrer"&gt;Microsoft Power Automate&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Power Automate is part of Microsoft's automation ecosystem.&lt;/p&gt;

&lt;p&gt;It allows you to automate processes across services such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Outlook&lt;/li&gt;
&lt;li&gt;Excel&lt;/li&gt;
&lt;li&gt;SharePoint&lt;/li&gt;
&lt;li&gt;Teams&lt;/li&gt;
&lt;li&gt;OneDrive&lt;/li&gt;
&lt;li&gt;SQL databases&lt;/li&gt;
&lt;li&gt;HTTP APIs&lt;/li&gt;
&lt;li&gt;Microsoft 365&lt;/li&gt;
&lt;li&gt;Other third-party services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also includes &lt;strong&gt;Power Automate Desktop&lt;/strong&gt;, which allows you to automate tasks performed directly on a Windows computer.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open browser
    ↓
Go to website
    ↓
Login
    ↓
Download report
    ↓
Open Excel
    ↓
Process data
    ↓
Save file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Power Automate is a good starting point, especially if you work in organizations that already use Microsoft 365 and Azure.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;a href="https://www.uipath.com/" rel="noopener noreferrer"&gt;UiPath&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;UiPath is another major RPA platform.&lt;/p&gt;

&lt;p&gt;It provides tools for building, deploying and managing software robots.&lt;/p&gt;

&lt;p&gt;Important UiPath concepts include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UiPath Studio&lt;/li&gt;
&lt;li&gt;Activities&lt;/li&gt;
&lt;li&gt;Variables&lt;/li&gt;
&lt;li&gt;Arguments&lt;/li&gt;
&lt;li&gt;Selectors&lt;/li&gt;
&lt;li&gt;DataTables&lt;/li&gt;
&lt;li&gt;Workflows&lt;/li&gt;
&lt;li&gt;Exception handling&lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Queues&lt;/li&gt;
&lt;li&gt;Orchestrator&lt;/li&gt;
&lt;li&gt;Robots&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;UiPath is worth learning if you want to pursue RPA as a dedicated career path.&lt;/p&gt;

&lt;h1&gt;
  
  
  What should you learn first?
&lt;/h1&gt;

&lt;p&gt;Do not try to learn everything at once.&lt;/p&gt;

&lt;p&gt;A good learning path looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RPA Fundamentals
       ↓
Power Automate Desktop
       ↓
UiPath
       ↓
Web Automation
       ↓
Excel &amp;amp; Data Processing
       ↓
APIs
       ↓
SQL
       ↓
Python
       ↓
Enterprise RPA
       ↓
AI + RPA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break this down.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Learn RPA fundamentals
&lt;/h1&gt;

&lt;p&gt;Before learning a specific tool, understand the basic concepts.&lt;/p&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What RPA is&lt;/li&gt;
&lt;li&gt;What RPA is not&lt;/li&gt;
&lt;li&gt;RPA use cases&lt;/li&gt;
&lt;li&gt;Attended automation&lt;/li&gt;
&lt;li&gt;Unattended automation&lt;/li&gt;
&lt;li&gt;Rule-based processes&lt;/li&gt;
&lt;li&gt;Process discovery&lt;/li&gt;
&lt;li&gt;Workflow design&lt;/li&gt;
&lt;li&gt;Exceptions&lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One important concept is &lt;strong&gt;process discovery&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before building a bot, you should understand the process you are trying to automate.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What starts the process?
        ↓
What information is required?
        ↓
What applications are used?
        ↓
What decisions are made?
        ↓
What can go wrong?
        ↓
What should happen when something fails?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an important skill for an RPA developer.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Learn Power Automate Desktop
&lt;/h1&gt;

&lt;p&gt;Once you understand the basics, build simple desktop automations.&lt;/p&gt;

&lt;p&gt;Start with:&lt;/p&gt;

&lt;h3&gt;
  
  
  Automation 1 - File management
&lt;/h3&gt;

&lt;p&gt;Build a bot that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find files in a folder
       ↓
Read filenames
       ↓
Create folders
       ↓
Move files
       ↓
Generate a summary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Automation 2 - Excel
&lt;/h3&gt;

&lt;p&gt;Build an automation that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open Excel
     ↓
Read data
     ↓
Filter records
     ↓
Calculate values
     ↓
Create a report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Automation 3 - Email
&lt;/h3&gt;

&lt;p&gt;Build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Check email
    ↓
Find messages matching a condition
    ↓
Download attachments
    ↓
Process attachment
    ↓
Send response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Automation 4 - Browser
&lt;/h3&gt;

&lt;p&gt;Build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open browser
     ↓
Navigate to website
     ↓
Login
     ↓
Read information
     ↓
Save information
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These simple projects will teach you many of the concepts used in real RPA work.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Learn UiPath
&lt;/h1&gt;

&lt;p&gt;Once you are comfortable with basic automation, start learning UiPath.&lt;/p&gt;

&lt;p&gt;Focus on understanding:&lt;/p&gt;

&lt;h3&gt;
  
  
  Activities
&lt;/h3&gt;

&lt;p&gt;Activities are the building blocks of UiPath workflows.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open browser&lt;/li&gt;
&lt;li&gt;Click&lt;/li&gt;
&lt;li&gt;Type&lt;/li&gt;
&lt;li&gt;Read text&lt;/li&gt;
&lt;li&gt;Read Excel&lt;/li&gt;
&lt;li&gt;Write Excel&lt;/li&gt;
&lt;li&gt;Send email&lt;/li&gt;
&lt;li&gt;Create file&lt;/li&gt;
&lt;li&gt;Move file&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Variables
&lt;/h3&gt;

&lt;p&gt;Learn how to store information inside your automation.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerName
invoiceNumber
amount
emailAddress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conditions
&lt;/h3&gt;

&lt;p&gt;Learn how to make the bot behave differently depending on the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IF amount &amp;gt; 100000
    send for approval
ELSE
    process automatically
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Loops
&lt;/h3&gt;

&lt;p&gt;Learn how to process multiple records.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For each customer
    Validate customer
    Update system
    Generate result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Selectors
&lt;/h3&gt;

&lt;p&gt;Selectors are particularly important in UI automation.&lt;/p&gt;

&lt;p&gt;They allow an RPA tool to identify elements on a webpage or application.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Username field
Password field
Login button
Submit button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Understanding selectors will help you build more reliable automations.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Learn Excel and data processing
&lt;/h1&gt;

&lt;p&gt;A lot of business automation involves data.&lt;/p&gt;

&lt;p&gt;You should become comfortable with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Excel&lt;/li&gt;
&lt;li&gt;CSV&lt;/li&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;li&gt;XML&lt;/li&gt;
&lt;li&gt;DataTables&lt;/li&gt;
&lt;li&gt;Basic data validation&lt;/li&gt;
&lt;li&gt;Filtering&lt;/li&gt;
&lt;li&gt;Sorting&lt;/li&gt;
&lt;li&gt;Transformations&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Excel
   ↓
Validate records
   ↓
Remove duplicates
   ↓
Transform data
   ↓
Send to API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should also learn basic SQL.&lt;/p&gt;

&lt;p&gt;At minimum, understand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 5: Learn APIs
&lt;/h1&gt;

&lt;p&gt;This is one of the most valuable skills you can add to RPA.&lt;/p&gt;

&lt;p&gt;Modern automation does not always need to interact with a website through clicks.&lt;/p&gt;

&lt;p&gt;If a system provides an API, you can often integrate with it directly.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RPA Bot
   ↓
Open browser
   ↓
Click login
   ↓
Click menu
   ↓
Click customer
   ↓
Enter information
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you may be able to do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RPA
 ↓
REST API
 ↓
Business System
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST APIs&lt;/li&gt;
&lt;li&gt;HTTP methods&lt;/li&gt;
&lt;li&gt;GET&lt;/li&gt;
&lt;li&gt;POST&lt;/li&gt;
&lt;li&gt;PUT/PATCH&lt;/li&gt;
&lt;li&gt;DELETE&lt;/li&gt;
&lt;li&gt;Headers&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;OAuth 2.0&lt;/li&gt;
&lt;li&gt;API keys&lt;/li&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;li&gt;Webhooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where RPA starts connecting with traditional software engineering.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Learn Python
&lt;/h1&gt;

&lt;p&gt;Python is not mandatory for RPA, but it can make you much more capable.&lt;/p&gt;

&lt;p&gt;You can use Python for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data processing&lt;/li&gt;
&lt;li&gt;File manipulation&lt;/li&gt;
&lt;li&gt;API integration&lt;/li&gt;
&lt;li&gt;Complex business logic&lt;/li&gt;
&lt;li&gt;Data transformation&lt;/li&gt;
&lt;li&gt;Automation scripts&lt;/li&gt;
&lt;li&gt;AI integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Useful libraries include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pandas&lt;/li&gt;
&lt;li&gt;requests&lt;/li&gt;
&lt;li&gt;openpyxl&lt;/li&gt;
&lt;li&gt;Playwright&lt;/li&gt;
&lt;li&gt;Selenium&lt;/li&gt;
&lt;li&gt;PyAutoGUI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For web automation, Playwright is particularly useful to learn.&lt;/p&gt;

&lt;p&gt;You can eventually build workflows such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RPA
 ↓
Python
 ↓
Process data
 ↓
REST API
 ↓
Database
 ↓
RPA
 ↓
Email notification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 7: Learn enterprise RPA
&lt;/h1&gt;

&lt;p&gt;After learning the basics, start thinking about how automation works in real organizations.&lt;/p&gt;

&lt;p&gt;This introduces concepts such as:&lt;/p&gt;

&lt;h3&gt;
  
  
  Attended automation
&lt;/h3&gt;

&lt;p&gt;A user starts or interacts with the automation.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Employee
   ↓
Starts bot
   ↓
Bot processes task
   ↓
Employee continues
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Unattended automation
&lt;/h3&gt;

&lt;p&gt;The automation runs without someone sitting in front of the computer.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2:00 AM
   ↓
Robot starts
   ↓
Processes 5,000 records
   ↓
Generates report
   ↓
Sends notification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should also learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Queues&lt;/li&gt;
&lt;li&gt;Scheduling&lt;/li&gt;
&lt;li&gt;Credentials&lt;/li&gt;
&lt;li&gt;Secrets&lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Monitoring&lt;/li&gt;
&lt;li&gt;Retry mechanisms&lt;/li&gt;
&lt;li&gt;Exception handling&lt;/li&gt;
&lt;li&gt;Audit trails&lt;/li&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;li&gt;Version control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These concepts become important when automations are running in production.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 8: Learn AI + RPA
&lt;/h1&gt;

&lt;p&gt;This is an exciting area because AI can extend what traditional RPA can do.&lt;/p&gt;

&lt;p&gt;Traditional RPA is generally good at structured, predictable tasks.&lt;/p&gt;

&lt;p&gt;AI can help with less structured information.&lt;/p&gt;

&lt;p&gt;For example, consider invoices.&lt;/p&gt;

&lt;p&gt;A traditional RPA workflow might expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invoice number = cell A1
Amount = cell B1
Date = cell C1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But invoices can have different layouts.&lt;/p&gt;

&lt;p&gt;AI can help extract information from documents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invoice
   ↓
OCR / Document AI
   ↓
Extract information
   ↓
Validate
   ↓
RPA
   ↓
Update accounting system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can eventually learn technologies such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OCR&lt;/li&gt;
&lt;li&gt;Intelligent Document Processing&lt;/li&gt;
&lt;li&gt;Azure AI Document Intelligence&lt;/li&gt;
&lt;li&gt;Large Language Models&lt;/li&gt;
&lt;li&gt;Structured AI output&lt;/li&gt;
&lt;li&gt;AI agents&lt;/li&gt;
&lt;li&gt;Human-in-the-loop workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This combination is often referred to as intelligent automation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Build projects instead of only watching tutorials
&lt;/h1&gt;

&lt;p&gt;One of the biggest mistakes beginners make is spending months watching tutorials without building anything.&lt;/p&gt;

&lt;p&gt;After learning a concept, build something.&lt;/p&gt;

&lt;p&gt;Here are some beginner projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project 1 - Employee onboarding
&lt;/h2&gt;

&lt;p&gt;Build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New employee information
        ↓
Validate information
        ↓
Create folder
        ↓
Generate documents
        ↓
Send welcome email
        ↓
Notify HR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Project 2 - Invoice processing
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invoice arrives by email
        ↓
Download attachment
        ↓
Extract information
        ↓
Validate invoice
        ↓
Store information
        ↓
Send notification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Project 3 - Daily reporting
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scheduled automation
        ↓
Retrieve data
        ↓
Process data
        ↓
Generate Excel report
        ↓
Send email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Project 4 - Customer data synchronization
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System A
    ↓
API
    ↓
Transform data
    ↓
System B
    ↓
Log result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Project 5 - AI document processing
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Document
   ↓
AI extraction
   ↓
Validate information
   ↓
Human approval if necessary
   ↓
RPA/API
   ↓
Business system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  RPA skills checklist
&lt;/h1&gt;

&lt;p&gt;As you progress, you can use this checklist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beginner
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Understand RPA&lt;/li&gt;
&lt;li&gt;[ ] Identify automation opportunities&lt;/li&gt;
&lt;li&gt;[ ] Understand workflows&lt;/li&gt;
&lt;li&gt;[ ] Power Automate Desktop&lt;/li&gt;
&lt;li&gt;[ ] Basic UiPath&lt;/li&gt;
&lt;li&gt;[ ] Excel automation&lt;/li&gt;
&lt;li&gt;[ ] File automation&lt;/li&gt;
&lt;li&gt;[ ] Email automation&lt;/li&gt;
&lt;li&gt;[ ] Browser automation&lt;/li&gt;
&lt;li&gt;[ ] Conditions&lt;/li&gt;
&lt;li&gt;[ ] Loops&lt;/li&gt;
&lt;li&gt;[ ] Variables&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Intermediate
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] UiPath selectors&lt;/li&gt;
&lt;li&gt;[ ] Exception handling&lt;/li&gt;
&lt;li&gt;[ ] Logging&lt;/li&gt;
&lt;li&gt;[ ] Debugging&lt;/li&gt;
&lt;li&gt;[ ] DataTables&lt;/li&gt;
&lt;li&gt;[ ] SQL&lt;/li&gt;
&lt;li&gt;[ ] REST APIs&lt;/li&gt;
&lt;li&gt;[ ] JSON&lt;/li&gt;
&lt;li&gt;[ ] OAuth&lt;/li&gt;
&lt;li&gt;[ ] Python&lt;/li&gt;
&lt;li&gt;[ ] Playwright&lt;/li&gt;
&lt;li&gt;[ ] Power Automate Cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advanced
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] UiPath Orchestrator&lt;/li&gt;
&lt;li&gt;[ ] Queues&lt;/li&gt;
&lt;li&gt;[ ] Unattended automation&lt;/li&gt;
&lt;li&gt;[ ] Credentials and secrets&lt;/li&gt;
&lt;li&gt;[ ] Monitoring&lt;/li&gt;
&lt;li&gt;[ ] CI/CD&lt;/li&gt;
&lt;li&gt;[ ] Version control&lt;/li&gt;
&lt;li&gt;[ ] Enterprise architecture&lt;/li&gt;
&lt;li&gt;[ ] Intelligent Document Processing&lt;/li&gt;
&lt;li&gt;[ ] AI integration&lt;/li&gt;
&lt;li&gt;[ ] AI agents&lt;/li&gt;
&lt;li&gt;[ ] Human-in-the-loop automation&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Do you need to learn everything?
&lt;/h1&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;You don't need to become an expert in UiPath, Power Automate, Python, APIs, SQL and AI before building your first bot.&lt;/p&gt;

&lt;p&gt;Start small.&lt;/p&gt;

&lt;p&gt;A practical progression is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Learn RPA concepts
       ↓
Build a simple desktop automation
       ↓
Automate Excel
       ↓
Automate email
       ↓
Automate a website
       ↓
Learn APIs
       ↓
Learn SQL
       ↓
Learn Python
       ↓
Build enterprise workflows
       ↓
Add AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The most valuable skill is not knowing how to click around an RPA platform.&lt;/p&gt;

&lt;p&gt;It is learning how to look at a business process and answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What part of this process can be automated, how should it be automated, and how can I make the automation reliable?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you develop that ability, learning another RPA platform becomes much easier.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final thoughts
&lt;/h1&gt;

&lt;p&gt;RPA sits at an interesting intersection between &lt;strong&gt;software engineering, business processes and automation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can start without being a programmer, but programming, APIs, databases and cloud technologies can significantly expand what you are able to build.&lt;/p&gt;

&lt;p&gt;A strong long-term skill set could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Automation Engineer
                        |
        +---------------+---------------+
        |               |               |
       RPA             APIs            AI
        |               |               |
   UiPath / PA      REST / OAuth      LLMs
        |               |               |
   Desktop/Web       Python/SQL      Agents
        |               |               |
        +---------------+---------------+
                        |
                 Business Automation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are starting today, don't try to learn ten tools simultaneously.&lt;/p&gt;

&lt;p&gt;Start with &lt;strong&gt;Power Automate Desktop or UiPath&lt;/strong&gt;, build a few real automations, then add &lt;strong&gt;APIs, SQL and Python&lt;/strong&gt;. Once you understand those foundations, explore &lt;strong&gt;AI-powered automation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That progression can take you from building simple bots to designing complete business automation solutions.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>powerautomate</category>
      <category>rpa</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understanding Retrieval-Augmented Generation (RAG)</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Fri, 18 Sep 2026 15:40:46 +0000</pubDate>
      <link>https://dev.to/msnmongare/understanding-retrieval-augmented-generation-rag-331e</link>
      <guid>https://dev.to/msnmongare/understanding-retrieval-augmented-generation-rag-331e</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Large Language Models (LLMs) have changed how we interact with software. They can answer questions, summarize documents, generate code, analyze information, and perform many other tasks using natural language.&lt;/p&gt;

&lt;p&gt;However, LLMs have an important limitation: they do not automatically know everything about your organization, your internal documents, or information that has changed since their training.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Retrieval-Augmented Generation (RAG)&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;RAG is an AI architecture that allows an LLM to retrieve relevant information from an external knowledge source before generating a response. Instead of relying entirely on what the model learned during training, the system first searches a collection of trusted information, retrieves relevant content, and provides that content to the LLM as context.&lt;/p&gt;

&lt;p&gt;A simple way to think about RAG is an &lt;strong&gt;open-book exam&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of asking the AI to answer a question entirely from memory, you give it access to the relevant documents first. The AI searches those documents, finds the information it needs, and then uses that information to formulate an answer.&lt;/p&gt;

&lt;p&gt;For example, imagine an employee asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What is our company's Q3 remote work policy?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A general-purpose LLM may not know the company's internal policy. With RAG, the system can search the organization's policy documents, retrieve the relevant section, provide it to the LLM, and generate an answer based on that information.&lt;/p&gt;

&lt;p&gt;This makes RAG particularly useful for organizations working with proprietary, domain-specific, or frequently changing information.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Two Major Pipelines of RAG
&lt;/h1&gt;

&lt;p&gt;A complete RAG system can be thought of as having two major pipelines:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Data Preparation Pipeline&lt;/strong&gt;, also called ingestion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Runtime Pipeline&lt;/strong&gt;, which happens when a user asks a question&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Understanding this distinction is important because RAG does not simply mean "put documents into an AI model."&lt;/p&gt;

&lt;p&gt;There is significant work that happens before the user ever asks a question.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. The Data Preparation Pipeline
&lt;/h1&gt;

&lt;p&gt;The first step is preparing your data so that an AI system can efficiently search and retrieve relevant information.&lt;/p&gt;

&lt;p&gt;Your source data could come from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PDF documents&lt;/li&gt;
&lt;li&gt;Word documents&lt;/li&gt;
&lt;li&gt;Internal company wikis&lt;/li&gt;
&lt;li&gt;Websites&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;SharePoint&lt;/li&gt;
&lt;li&gt;Emails&lt;/li&gt;
&lt;li&gt;Knowledge bases&lt;/li&gt;
&lt;li&gt;API responses&lt;/li&gt;
&lt;li&gt;Internal documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The general process looks like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documents -&amp;gt; Chunking -&amp;gt; Embeddings -&amp;gt; Vector Database&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Chunking
&lt;/h2&gt;

&lt;p&gt;Large documents are usually too big to retrieve as a single piece.&lt;/p&gt;

&lt;p&gt;Imagine having a 200-page employee handbook. If someone asks about the company's leave policy, you don't want to retrieve the entire 200-page document.&lt;/p&gt;

&lt;p&gt;Instead, the document is divided into smaller pieces called &lt;strong&gt;chunks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A chunk might contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A paragraph&lt;/li&gt;
&lt;li&gt;Several paragraphs&lt;/li&gt;
&lt;li&gt;A section&lt;/li&gt;
&lt;li&gt;A group of related sentences&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Employee Handbook
        |
        v
+-------------------+
| Chunk 1           |
| Introduction      |
+-------------------+
| Chunk 2           |
| Leave Policy      |
+-------------------+
| Chunk 3           |
| Remote Work       |
+-------------------+
| Chunk 4           |
| Benefits          |
+-------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is to create chunks that contain enough information to be useful while remaining small enough for efficient retrieval.&lt;/p&gt;

&lt;p&gt;Chunking is more important than it might initially appear. Poorly chosen chunks can result in the system retrieving incomplete or irrelevant information, which can ultimately affect the quality of the generated answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Embedding
&lt;/h2&gt;

&lt;p&gt;Once the documents have been divided into chunks, each chunk is passed through an &lt;strong&gt;embedding model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An embedding model converts text into a numerical representation called a &lt;strong&gt;vector embedding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, a sentence such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Employees can work remotely three days per week."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;is converted into a mathematical representation containing many numbers.&lt;/p&gt;

&lt;p&gt;The important idea is that the vector represents the semantic meaning of the text.&lt;/p&gt;

&lt;p&gt;This allows a system to identify relationships between concepts rather than simply matching exact words.&lt;/p&gt;

&lt;p&gt;For example, a user might ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How many days can I work from home?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The document might contain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Employees can work remotely three days per week."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even though the wording is different, the system can recognize that the two pieces of text are semantically related.&lt;/p&gt;




&lt;h2&gt;
  
  
  Storing the Embeddings
&lt;/h2&gt;

&lt;p&gt;The generated embeddings are stored in a &lt;strong&gt;vector database&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ChromaDB&lt;/li&gt;
&lt;li&gt;Pinecone&lt;/li&gt;
&lt;li&gt;Weaviate&lt;/li&gt;
&lt;li&gt;pgvector&lt;/li&gt;
&lt;li&gt;Qdrant&lt;/li&gt;
&lt;li&gt;Milvus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The vector database acts as a searchable index for the knowledge base.&lt;/p&gt;

&lt;p&gt;A simplified representation might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Document Chunk
      |
      v
Embedding Model
      |
      v
Vector
[0.021, -0.183, 0.492, ...]
      |
      v
Vector Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database can then perform similarity searches to identify which pieces of information are most relevant to a user's question.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. The Runtime Pipeline
&lt;/h1&gt;

&lt;p&gt;The second part of RAG happens when a user actually interacts with the application.&lt;/p&gt;

&lt;p&gt;This is the part most people associate with RAG.&lt;/p&gt;

&lt;p&gt;The basic process is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Query
     |
     v
Retrieval
     |
     v
Retrieved Context
     |
     v
Augmentation
     |
     v
LLM
     |
     v
Generated Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are three core stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieval&lt;/li&gt;
&lt;li&gt;Augmentation&lt;/li&gt;
&lt;li&gt;Generation&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 1: Retrieval
&lt;/h2&gt;

&lt;p&gt;The user submits a question.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"What is our company's Q3 remote work policy?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system converts the question into an embedding using the same or a compatible embedding model used during ingestion.&lt;/p&gt;

&lt;p&gt;It then searches the vector database for chunks that are semantically similar to the query.&lt;/p&gt;

&lt;p&gt;The vector database might return something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Chunk 1:
"Employees are required to work from the office..."

Chunk 2:
"Employees may work remotely up to three days per week..."

Chunk 3:
"Remote employees must remain available during..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system selects the most relevant chunks to provide as context to the LLM.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;retrieval&lt;/strong&gt; part of Retrieval-Augmented Generation.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 2: Augmentation
&lt;/h1&gt;

&lt;p&gt;The retrieved information is then combined with the user's original question.&lt;/p&gt;

&lt;p&gt;The application typically uses a prompt template to tell the LLM how to use the retrieved information.&lt;/p&gt;

&lt;p&gt;Conceptually, it could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use the following information to answer the user's question.

Context:
Employees may work remotely up to three days per week.
Remote employees must remain available during
normal working hours.

Question:
What is our company's Q3 remote work policy?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM now has access to information that was retrieved specifically for the user's question.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;augmentation&lt;/strong&gt; part of RAG.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 3: Generation
&lt;/h1&gt;

&lt;p&gt;The augmented prompt is sent to the LLM.&lt;/p&gt;

&lt;p&gt;The model uses the retrieved context, together with its language understanding and reasoning capabilities, to generate the final response.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"According to the company's policy, employees may work remotely up to three days per week while remaining available during normal working hours."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the &lt;strong&gt;generation&lt;/strong&gt; part of RAG.&lt;/p&gt;

&lt;p&gt;Putting everything together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                   DATA PREPARATION
                   -----------------

Documents
    |
    v
Chunking
    |
    v
Embedding Model
    |
    v
Vector Database
    |
    |
    |                    RUNTIME
    |                    -------
    |                       |
    |                  User Question
    |                       |
    |                       v
    +--------------&amp;gt;  Query Embedding
                            |
                            v
                     Similarity Search
                            |
                            v
                    Relevant Chunks
                            |
                            v
                       Prompt + Context
                            |
                            v
                           LLM
                            |
                            v
                     Generated Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Why Organizations Use RAG
&lt;/h1&gt;

&lt;p&gt;RAG is particularly useful for organizations that need AI systems to work with their own data.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Grounding AI Responses
&lt;/h2&gt;

&lt;p&gt;LLMs can sometimes generate information that sounds convincing but is incorrect. This is commonly referred to as &lt;strong&gt;hallucination&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;RAG can reduce this problem by providing the model with relevant source information before it generates an answer.&lt;/p&gt;

&lt;p&gt;However, RAG does not magically eliminate hallucinations.&lt;/p&gt;

&lt;p&gt;If the retrieval system returns irrelevant information, incomplete information, or outdated information, the LLM can still produce a poor answer.&lt;/p&gt;

&lt;p&gt;This is why the quality of the retrieval system is just as important as the LLM itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Easier Knowledge Updates
&lt;/h2&gt;

&lt;p&gt;Suppose a company changes its leave policy.&lt;/p&gt;

&lt;p&gt;With a traditional approach, you might consider retraining or fine-tuning a model to incorporate the new information.&lt;/p&gt;

&lt;p&gt;With RAG, you can update the underlying knowledge base.&lt;/p&gt;

&lt;p&gt;The new document can be processed, chunked, embedded, and added to the vector database.&lt;/p&gt;

&lt;p&gt;The LLM itself does not need to be retrained simply because the organization's documentation changed.&lt;/p&gt;

&lt;p&gt;This makes RAG particularly useful for information that changes frequently.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Working With Private Data
&lt;/h2&gt;

&lt;p&gt;Organizations have large amounts of internal information that general-purpose AI models were not trained on.&lt;/p&gt;

&lt;p&gt;This could include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Internal policies&lt;/li&gt;
&lt;li&gt;Product documentation&lt;/li&gt;
&lt;li&gt;Customer support information&lt;/li&gt;
&lt;li&gt;Financial reports&lt;/li&gt;
&lt;li&gt;Technical documentation&lt;/li&gt;
&lt;li&gt;Employee handbooks&lt;/li&gt;
&lt;li&gt;Business processes&lt;/li&gt;
&lt;li&gt;Internal knowledge bases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RAG provides a way to build an AI interface over this information while keeping the organization's knowledge source separate from the underlying LLM.&lt;/p&gt;

&lt;p&gt;Of course, privacy and security still need to be designed carefully. Access controls, authentication, authorization, data isolation, logging, and appropriate handling of sensitive information remain important.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Cost and Maintenance
&lt;/h2&gt;

&lt;p&gt;Continuously retraining a large language model whenever an organization's information changes is generally impractical.&lt;/p&gt;

&lt;p&gt;RAG separates the &lt;strong&gt;knowledge layer&lt;/strong&gt; from the &lt;strong&gt;language model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The LLM handles language understanding and generation, while the retrieval system provides the relevant organizational knowledge.&lt;/p&gt;

&lt;p&gt;This separation makes it easier to maintain and update the knowledge source independently.&lt;/p&gt;




&lt;h1&gt;
  
  
  RAG Is More Than a Vector Database
&lt;/h1&gt;

&lt;p&gt;One common misconception is that building a RAG system simply means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Put documents into a vector database and connect it to an LLM."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In practice, there are several components involved.&lt;/p&gt;

&lt;p&gt;A production RAG system may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Document ingestion&lt;/li&gt;
&lt;li&gt;Text extraction&lt;/li&gt;
&lt;li&gt;Chunking&lt;/li&gt;
&lt;li&gt;Embedding models&lt;/li&gt;
&lt;li&gt;Vector databases&lt;/li&gt;
&lt;li&gt;Metadata filtering&lt;/li&gt;
&lt;li&gt;Keyword search&lt;/li&gt;
&lt;li&gt;Semantic search&lt;/li&gt;
&lt;li&gt;Hybrid search&lt;/li&gt;
&lt;li&gt;Reranking&lt;/li&gt;
&lt;li&gt;Prompt engineering&lt;/li&gt;
&lt;li&gt;LLMs&lt;/li&gt;
&lt;li&gt;Access control&lt;/li&gt;
&lt;li&gt;Observability&lt;/li&gt;
&lt;li&gt;Evaluation&lt;/li&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Data freshness mechanisms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means RAG is better understood as an &lt;strong&gt;architecture&lt;/strong&gt; rather than a single technology.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Importance of Retrieval Quality
&lt;/h1&gt;

&lt;p&gt;One of the most important lessons when building RAG systems is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A better LLM cannot always compensate for poor retrieval.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine a user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What is the company's maternity leave policy?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the retrieval system returns documents about annual leave.&lt;/p&gt;

&lt;p&gt;The LLM now has the wrong context.&lt;/p&gt;

&lt;p&gt;Even if the LLM is extremely capable, it may generate an answer based on irrelevant information.&lt;/p&gt;

&lt;p&gt;A simplified way to think about the process is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Good Retrieval
      +
Relevant Context
      +
Good LLM
      =
Useful Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Poor Retrieval
      +
Wrong Context
      +
Good LLM
      =
Potentially Wrong Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why RAG evaluation needs to look beyond the final response. You also need to evaluate whether the system retrieved the right information in the first place.&lt;/p&gt;




&lt;h1&gt;
  
  
  RAG and Traditional LLM Applications
&lt;/h1&gt;

&lt;p&gt;A standard LLM application might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
  |
  v
LLM
  |
  v
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model relies primarily on the information encoded in its parameters during training, plus whatever information is included in the current conversation or prompt.&lt;/p&gt;

&lt;p&gt;A RAG application adds an external knowledge layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                  +----------------+
                  | Knowledge Base |
                  +-------+--------+
                          |
                          v
User -&amp;gt; Retrieval -&amp;gt; Context -&amp;gt; LLM -&amp;gt; Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This architectural difference is what makes RAG useful for organization-specific knowledge.&lt;/p&gt;




&lt;h1&gt;
  
  
  A Practical Example
&lt;/h1&gt;

&lt;p&gt;Consider a healthcare organization with thousands of documents.&lt;/p&gt;

&lt;p&gt;An employee asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What is the process for approving a medical claim?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without RAG, the LLM may have general knowledge about medical claims, but it does not necessarily know the organization's specific process.&lt;/p&gt;

&lt;p&gt;With RAG:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Question
     |
     v
Search Knowledge Base
     |
     v
Retrieve Claims Procedure
     |
     v
Add Procedure to Prompt
     |
     v
LLM
     |
     v
Answer Based on Retrieved Procedure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same architecture can be applied to many other domains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Banking&lt;/li&gt;
&lt;li&gt;Insurance&lt;/li&gt;
&lt;li&gt;Healthcare&lt;/li&gt;
&lt;li&gt;Education&lt;/li&gt;
&lt;li&gt;Legal documentation&lt;/li&gt;
&lt;li&gt;Customer support&lt;/li&gt;
&lt;li&gt;Enterprise IT&lt;/li&gt;
&lt;li&gt;Human resources&lt;/li&gt;
&lt;li&gt;Government services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anywhere an organization has a large collection of documents or structured knowledge, RAG can potentially provide a useful interface for accessing that information.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Retrieval-Augmented Generation is one of the most practical architectures for connecting LLMs to external knowledge.&lt;/p&gt;

&lt;p&gt;The fundamental idea is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retrieve relevant information first, then let the LLM generate an answer using that information.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A RAG system generally consists of two major phases.&lt;/p&gt;

&lt;p&gt;During &lt;strong&gt;data preparation&lt;/strong&gt;, documents are collected, chunked, converted into embeddings, and stored in a searchable knowledge store.&lt;/p&gt;

&lt;p&gt;During &lt;strong&gt;runtime&lt;/strong&gt;, a user's question is converted into a searchable representation, relevant information is retrieved, that information is added to the prompt, and the LLM generates the final response.&lt;/p&gt;

&lt;p&gt;The important thing to remember is that RAG is not just about the LLM. The quality of the entire pipeline matters - from how documents are processed and chunked, to how information is retrieved, filtered, ranked, and finally presented to the model.&lt;/p&gt;

&lt;p&gt;As organizations look for practical ways to use AI with their own data, understanding RAG provides an important foundation for building AI applications that are connected to real, domain-specific knowledge rather than relying solely on what a model learned during training.&lt;/p&gt;

</description>
      <category>rag</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What is Grok Bot? The Complete Beginner's Guide and Use Cases</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Fri, 18 Sep 2026 06:57:56 +0000</pubDate>
      <link>https://dev.to/msnmongare/what-is-grok-bot-the-complete-beginners-guide-and-use-cases-58hn</link>
      <guid>https://dev.to/msnmongare/what-is-grok-bot-the-complete-beginners-guide-and-use-cases-58hn</guid>
      <description>&lt;p&gt;Imagine having a personal assistant who doesn't just type out answers, but actually sits down at a computer, opens a web browser, fills out forms, and organizes files for you. That is exactly what Grok Bot does.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;As artificial intelligence evolves, we are moving away from simple chatbots and entering the era of AI "agents"—programs that can actively execute multi-step tasks. In this guide, we will break down what Grok Bot is, how it works, and how you can use it to automate your daily digital chores.&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Grok Bot?
&lt;/h3&gt;

&lt;p&gt;At its core, &lt;strong&gt;Grok Bot&lt;/strong&gt; is an autonomous AI assistant designed to interact with a computer just like a human would. Unlike traditional AI that only generates text or code, Grok Bot is equipped with a dedicated, persistent Linux virtual machine in the cloud.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;This cloud computer gives the bot its own:&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web Browser:&lt;/strong&gt; To navigate websites, click buttons, and log into portals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File Manager:&lt;/strong&gt; To download, organize, and edit documents or spreadsheets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminal:&lt;/strong&gt; To run commands and execute lightweight scripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because it operates on an independent cloud machine, it is always on. You can give Grok Bot a complex assignment, close your laptop, walk away, and it will keep working in the background until the job is done.&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  Top Use Cases for Grok Bot
&lt;/h3&gt;

&lt;p&gt;Because Grok Bot can use the internet and manage files, its practical applications are almost limitless. Here are the most common ways people use it:&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Automating Boring Workflows
&lt;/h3&gt;

&lt;p&gt;We all have repetitive digital tasks that eat up our time. Grok Bot can take over these chores entirely. For example, it can log into your company’s vendor portal every Friday, download invoice data, and manually type that information into an accounting spreadsheet. It is perfect for moving data between two software platforms that do not easily talk to each other.&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Deep Web Research and Monitoring
&lt;/h3&gt;

&lt;p&gt;Instead of spending hours searching the web, you can deploy Grok Bot to do the heavy lifting. It can scan competitor websites to track pricing changes, gather contact details from public directories to build lead lists, or monitor retail sites for hard-to-find inventory, instantly alerting you when an item comes back in stock.&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. File and Data Management
&lt;/h3&gt;

&lt;p&gt;If you deal with large volumes of data, Grok Bot can act as your digital organizer. It can look through a folder containing thousands of downloaded files, rename them based on specific rules, convert them from PDFs to text files, and filter out duplicate entries using its built-in terminal tools.&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Software and QA Testing
&lt;/h3&gt;

&lt;p&gt;For developers and businesses, Grok Bot can act as a real user. You can instruct it to visit your newly built website, click through the checkout process, and report back if any links are broken or if the system crashes.&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Else Should Beginners Know?
&lt;/h3&gt;

&lt;p&gt;Before you dive in, there are a few essential things to keep in mind to get the most out of your AI assistant:&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A Shared Environment:&lt;/strong&gt; If you build or deploy multiple bots under your account, they all share access to the same single cloud machine, file system, and browser sessions. This makes it easy for different bots to collaborate on the same set of files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security and Credentials:&lt;/strong&gt; Because Grok Bot needs to log into websites to do its job, you will need to manage security credentials. Always practice safe data habits by using secure credential managers or dedicated account permissions for your bot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beginner-Friendly Controls:&lt;/strong&gt; You don't need to be a computer programmer to use Grok Bot. You can guide it using plain, natural language instructions, and it will translate your goals into clicks, typing, and commands.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Grok Bot represents a massive leap forward in personal productivity. By pairing advanced artificial intelligence with a fully functional cloud computer, it transforms from a simple conversation partner into a capable digital worker. Whether you are trying to escape repetitive data entry, track market trends, or manage messy file directories, Grok Bot can handle the heavy lifting—leaving you free to focus on the work that actually matters.&lt;/p&gt;

</description>
      <category>twitter</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to deploy a Laravel app to a VPS</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Wed, 16 Sep 2026 18:57:04 +0000</pubDate>
      <link>https://dev.to/msnmongare/how-to-deploy-a-laravel-app-to-a-vps-1m7j</link>
      <guid>https://dev.to/msnmongare/how-to-deploy-a-laravel-app-to-a-vps-1m7j</guid>
      <description>&lt;p&gt;This is a beginner guide for a Laravel app where the pages and the API live in the same project. Blade is the frontend. Laravel routes under &lt;code&gt;/api&lt;/code&gt; are the backend. There is no separate Node server.&lt;/p&gt;

&lt;p&gt;Replace &lt;code&gt;YOUR_SERVER_IP&lt;/code&gt;, &lt;code&gt;YOUR_DOMAIN&lt;/code&gt;, &lt;code&gt;YOUR_APP&lt;/code&gt;, and &lt;code&gt;STRONG_PASSWORD&lt;/code&gt; with your own values. Do not copy a real password, &lt;code&gt;APP_KEY&lt;/code&gt;, or a private key into a chat, a screenshot, or git.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;A VPS is a Linux computer in a data center. Visitors type a domain. An A record points that domain at the server's IP. Nginx receives HTTPS and hands every URL to PHP.&lt;/p&gt;

&lt;p&gt;One Laravel app answers both kinds of request. They share &lt;code&gt;public/index.php&lt;/code&gt;, the same &lt;code&gt;.env&lt;/code&gt;, and the same MySQL database.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Request&lt;/th&gt;
&lt;th&gt;Who answers&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;https://YOUR_DOMAIN/&lt;/code&gt; and &lt;code&gt;/login&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Laravel &lt;code&gt;routes/web.php&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Blade pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;https://YOUR_DOMAIN/api/...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Laravel &lt;code&gt;routes/api.php&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The API in the same app&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MySQL&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;127.0.0.1:3306&lt;/code&gt; only&lt;/td&gt;
&lt;td&gt;Laravel's own database. It is not on the public internet&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There is no second port to open. PHP-FPM is a local socket, not a public port. Nginx is the only door.&lt;/p&gt;

&lt;p&gt;GitHub Actions cannot upload code until the server already has a folder, a database, &lt;code&gt;.env&lt;/code&gt;, Nginx, and an SSH key. Actions logs in as &lt;code&gt;deploy&lt;/code&gt;, not as your sudo account. A leaked GitHub key can update the app, but it cannot install packages or change the firewall.&lt;/p&gt;

&lt;p&gt;Two accounts, two jobs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;User&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;YOUR_SUDO_USER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The account you SSH in as. It has &lt;code&gt;sudo&lt;/code&gt;. On the Contabo server used for MtandaoBilling this account is &lt;code&gt;sos&lt;/code&gt;. A lot of VPS images do not give you a root password.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;deploy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Owns &lt;code&gt;/var/www/YOUR_DOMAIN&lt;/code&gt;, runs Composer and Artisan, and is the GitHub Actions login. It has no password.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;PHP itself runs as &lt;code&gt;www-data&lt;/code&gt;. That user must be able to write &lt;code&gt;storage/&lt;/code&gt; and &lt;code&gt;bootstrap/cache&lt;/code&gt; even though &lt;code&gt;deploy&lt;/code&gt; owns the files.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Log in, and do not SSH as deploy yet
&lt;/h2&gt;

&lt;p&gt;From your PC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh YOUR_SUDO_USER@YOUR_SERVER_IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are on the server. The prompt looks like &lt;code&gt;YOUR_SUDO_USER@your-server:~$&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Do not run &lt;code&gt;ssh deploy@YOUR_SERVER_IP&lt;/code&gt; from that prompt. &lt;code&gt;deploy&lt;/code&gt; has no password and, at this point, no SSH key. The server answers &lt;code&gt;Permission denied (publickey)&lt;/code&gt;. You are already on the machine. Switch user instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; deploy &lt;span class="nt"&gt;-i&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sudo&lt;/code&gt; means "run this as another user." &lt;code&gt;-u deploy -i&lt;/code&gt; opens a login shell as &lt;code&gt;deploy&lt;/code&gt;. Type &lt;code&gt;exit&lt;/code&gt; to go back to your sudo account.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt&lt;/code&gt;, Nginx, and MySQL stay on the sudo account. Files inside the app folder are edited as &lt;code&gt;deploy&lt;/code&gt;, after that user owns the folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Install what Laravel needs
&lt;/h2&gt;

&lt;p&gt;You do not need PM2. PHP-FPM already stays running. You do need Node once, on the machine that builds CSS and JavaScript. On the server, Composer installs PHP packages. Vite assets are usually built in GitHub Actions and uploaded, so the server does not have to run &lt;code&gt;npm&lt;/code&gt; if that build already happened.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nginx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Receives HTTPS and sends PHP files to PHP-FPM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;php8.3-fpm&lt;/code&gt; and PHP extensions&lt;/td&gt;
&lt;td&gt;Runs Blade pages and the &lt;code&gt;/api&lt;/code&gt; routes. &lt;code&gt;fpm&lt;/code&gt; is the PHP process Nginx talks to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;composer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Installs Laravel's PHP libraries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mysql-server&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Laravel's database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;certbot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gets a free HTTPS certificate from Let's Encrypt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;acl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lets &lt;code&gt;www-data&lt;/code&gt; write logs and sessions in a folder owned by &lt;code&gt;deploy&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ufw&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Firewall. Only SSH, HTTP, and HTTPS should be open&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As &lt;code&gt;YOUR_SUDO_USER&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nginx mysql-server certbot python3-certbot-nginx &lt;span class="se"&gt;\&lt;/span&gt;
  git curl unzip ufw acl &lt;span class="se"&gt;\&lt;/span&gt;
  php8.3-fpm php8.3-cli php8.3-mysql php8.3-mbstring php8.3-xml &lt;span class="se"&gt;\&lt;/span&gt;
  php8.3-curl php8.3-zip php8.3-bcmath php8.3-tokenizer

curl &lt;span class="nt"&gt;-sS&lt;/span&gt; https://getcomposer.org/installer | &lt;span class="nb"&gt;sudo &lt;/span&gt;php &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--install-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/local/bin &lt;span class="nt"&gt;--filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;composer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;php8.3-*&lt;/code&gt; is not in your Ubuntu version, install PHP 8.2 or newer and later point Nginx at that socket (&lt;code&gt;ls /run/php/&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Check that the commands exist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php &lt;span class="nt"&gt;-v&lt;/span&gt;
composer &lt;span class="nt"&gt;-V&lt;/span&gt;
nginx &lt;span class="nt"&gt;-v&lt;/span&gt;
mysql &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;deploy&lt;/code&gt; once, if it does not exist. &lt;code&gt;--disabled-password&lt;/code&gt; is deliberate. GitHub will log in with a key, not a password that can be guessed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;adduser &lt;span class="nt"&gt;--disabled-password&lt;/span&gt; &lt;span class="nt"&gt;--gecos&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open only SSH and the web ports. Do not open MySQL port 3306.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow OpenSSH
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow &lt;span class="s1"&gt;'Nginx Full'&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;OpenSSH&lt;/code&gt; keeps your current login alive. &lt;code&gt;Nginx Full&lt;/code&gt; is ports 80 and 443.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Make the app folder, and make deploy the owner
&lt;/h2&gt;

&lt;p&gt;Nginx will not use this folder as the website root. It uses &lt;code&gt;public/&lt;/code&gt; inside it. The rest of Laravel (&lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;app/&lt;/code&gt;, &lt;code&gt;vendor/&lt;/code&gt;) must stay outside the web root so visitors cannot download it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/www/YOUR_DOMAIN
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; deploy:deploy /var/www/YOUR_DOMAIN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;chown&lt;/code&gt; means "this user owns these files."&lt;/p&gt;

&lt;p&gt;A folder created earlier as root stays owned by root. &lt;code&gt;mkdir -p&lt;/code&gt; as &lt;code&gt;deploy&lt;/code&gt; does not change a folder that already exists, and &lt;code&gt;nano&lt;/code&gt; then fails with &lt;code&gt;Permission denied&lt;/code&gt;. Check with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-ld&lt;/span&gt; /var/www/YOUR_DOMAIN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The owner must be &lt;code&gt;deploy deploy&lt;/code&gt;. If it says &lt;code&gt;root root&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; deploy:deploy /var/www/YOUR_DOMAIN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Create the MySQL database
&lt;/h2&gt;

&lt;p&gt;The Linux user &lt;code&gt;deploy&lt;/code&gt; is not the database user. Create a separate MySQL user. In MySQL, &lt;code&gt;localhost&lt;/code&gt; and &lt;code&gt;127.0.0.1&lt;/code&gt; are two different accounts.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;localhost&lt;/code&gt; means "connect through a Unix socket." &lt;code&gt;127.0.0.1&lt;/code&gt; means "connect with TCP." If &lt;code&gt;.env&lt;/code&gt; says &lt;code&gt;DB_HOST=127.0.0.1&lt;/code&gt;, a user created only &lt;code&gt;@localhost&lt;/code&gt; is invisible. &lt;code&gt;ALTER USER&lt;/code&gt; for the TCP account then fails with &lt;code&gt;ERROR 1396&lt;/code&gt; because that account does not exist yet.&lt;/p&gt;

&lt;p&gt;PHP's MySQL driver can use MySQL 8's normal &lt;code&gt;caching_sha2_password&lt;/code&gt; plugin. You do not need &lt;code&gt;mysql_native_password&lt;/code&gt; unless this same database is also used by Prisma. This guide uses the normal plugin.&lt;/p&gt;

&lt;p&gt;As &lt;code&gt;YOUR_SUDO_USER&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sudo mysql&lt;/code&gt; works without a MySQL root password because Ubuntu lets the system admin in through the socket. Invent a long password. Call it &lt;code&gt;STRONG_PASSWORD&lt;/code&gt; here. Use the same string later in &lt;code&gt;.env&lt;/code&gt;. Do not reuse a password from a chat log.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;your_app&lt;/span&gt; &lt;span class="nb"&gt;CHARACTER&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;utf8mb4&lt;/span&gt; &lt;span class="k"&gt;COLLATE&lt;/span&gt; &lt;span class="n"&gt;utf8mb4_unicode_ci&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'your_app_user'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'127.0.0.1'&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="s1"&gt;'STRONG_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;your_app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'your_app_user'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'127.0.0.1'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;FLUSH&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;host&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'your_app_user'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;host&lt;/code&gt; column must include &lt;code&gt;127.0.0.1&lt;/code&gt;. Then type &lt;code&gt;exit&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Write &lt;code&gt;.env&lt;/code&gt; on the server only
&lt;/h2&gt;

&lt;p&gt;There is one &lt;code&gt;.env&lt;/code&gt;, at the Laravel project root, not a separate frontend file. GitHub must not upload it.&lt;/p&gt;

&lt;p&gt;As &lt;code&gt;deploy&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /var/www/YOUR_DOMAIN/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start from your project's &lt;code&gt;.env.example&lt;/code&gt; and set at least these. Leave &lt;code&gt;APP_KEY&lt;/code&gt; empty. Artisan fills it after Composer has run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP_NAME=YOUR_APP
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://YOUR_DOMAIN

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_app
DB_USERNAME=your_app_user
DB_PASSWORD=STRONG_PASSWORD

SESSION_DRIVER=database
CACHE_STORE=database
QUEUE_CONNECTION=database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;APP_DEBUG=false&lt;/code&gt; so a crash does not print secrets in the browser. The real error still goes to &lt;code&gt;storage/logs/laravel.log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SESSION_DRIVER=database&lt;/code&gt; is fine for a Laravel app that owns MySQL, but only after &lt;code&gt;php artisan migrate&lt;/code&gt; has created the &lt;code&gt;sessions&lt;/code&gt; table. If you want the first page to work before that migrate, set &lt;code&gt;SESSION_DRIVER=file&lt;/code&gt; and &lt;code&gt;CACHE_STORE=file&lt;/code&gt; instead. A 500 that says &lt;code&gt;no such table: sessions&lt;/code&gt; means the driver is &lt;code&gt;database&lt;/code&gt; and migrate has not run.&lt;/p&gt;

&lt;p&gt;As the sudo user, lock the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chown &lt;/span&gt;deploy:deploy /var/www/YOUR_DOMAIN/.env
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;600 /var/www/YOUR_DOMAIN/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;600&lt;/code&gt; means owner read/write, everyone else nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Install Nginx and the free certificate
&lt;/h2&gt;

&lt;p&gt;The website root is &lt;code&gt;public/&lt;/code&gt;, not the project root. If you point Nginx at &lt;code&gt;/var/www/YOUR_DOMAIN&lt;/code&gt;, visitors can request &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As &lt;code&gt;YOUR_SUDO_USER&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/nginx/sites-available/YOUR_DOMAIN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste this. Read the comments. They are the reason each line exists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;YOUR_DOMAIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Only public/ is on the internet. app/, .env, and vendor/ are not.&lt;/span&gt;
    &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/var/www/YOUR_DOMAIN/public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.php&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;access_log&lt;/span&gt; &lt;span class="n"&gt;/var/log/nginx/YOUR_APP.access.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;error_log&lt;/span&gt;  &lt;span class="n"&gt;/var/log/nginx/YOUR_APP.error.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;charset&lt;/span&gt; &lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;client_max_body_size&lt;/span&gt; &lt;span class="mi"&gt;20m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Real files (CSS, images, Vite /build) are sent as files.&lt;/span&gt;
    &lt;span class="c1"&gt;# Every other URL, including /api/..., goes to public/index.php.&lt;/span&gt;
    &lt;span class="c1"&gt;# Laravel then chooses web.php or api.php. Nginx does not split them.&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="n"&gt;/index.php?&lt;/span&gt;&lt;span class="nv"&gt;$query_string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;/favicon.ico&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kn"&gt;access_log&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kn"&gt;log_not_found&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;/robots.txt&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kn"&gt;access_log&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kn"&gt;log_not_found&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;error_page&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt; &lt;span class="n"&gt;/index.php&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# PHP-FPM socket. If this file does not exist, run: ls /run/php/&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt; &lt;span class="sr"&gt;\.php$&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;include&lt;/span&gt; &lt;span class="nc"&gt;snippets/fastcgi-php&lt;/span&gt;&lt;span class="s"&gt;.conf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;fastcgi_pass&lt;/span&gt; &lt;span class="s"&gt;unix:/run/php/php8.3-fpm.sock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;fastcgi_param&lt;/span&gt; &lt;span class="s"&gt;HTTPS&lt;/span&gt; &lt;span class="nv"&gt;$https&lt;/span&gt; &lt;span class="s"&gt;if_not_empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# Block .env and .git if they ever land inside public/.&lt;/span&gt;
    &lt;span class="c1"&gt;# /.well-known/ stays open so Certbot can prove you own the domain.&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt; &lt;span class="sr"&gt;/\.(?!well-known).*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;deny&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable the site and test it before you reload. &lt;code&gt;nginx -t&lt;/code&gt; stops a typo from taking every site on the server down.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /etc/nginx/sites-available/YOUR_DOMAIN /etc/nginx/sites-enabled/
&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 404 or a PHP error now is normal. The app is not uploaded yet.&lt;/p&gt;

&lt;p&gt;Then ask Let's Encrypt for a certificate. Certbot is free. The prompt "agree to register with the ACME server" is their terms, not a paid account. Type yes, and enter an email so they can warn you before a certificate expires.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; YOUR_DOMAIN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Certbot edits the Nginx file on the server. It adds port 443 and redirects HTTP to HTTPS. Do not copy those certificate paths into git.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Give GitHub a key that can log in as deploy
&lt;/h2&gt;

&lt;p&gt;A password in GitHub is worse than a key you can delete. The key has two halves:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Where it goes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;YOUR_APP_deploy.pub&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The server. This is public. It says "this key is allowed."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;YOUR_APP_deploy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your PC, then the GitHub secret. This is private. Never commit it, and never paste it into a chat.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On your PC, not inside the SSH session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"github-actions-YOUR_APP"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.ssh/YOUR_APP_deploy &lt;span class="nt"&gt;-N&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
scp ~/.ssh/YOUR_APP_deploy.pub YOUR_SUDO_USER@YOUR_SERVER_IP:~/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In PowerShell, if &lt;code&gt;~&lt;/code&gt; is not your user folder, use the full path, for example &lt;code&gt;C:\Users\ADMIN\.ssh\YOUR_APP_deploy.pub&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On the VPS, as &lt;code&gt;YOUR_SUDO_USER&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /home/deploy/.ssh
&lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /home/deploy/.ssh/authorized_keys &amp;lt; ~/YOUR_APP_deploy.pub
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; deploy:deploy /home/deploy/.ssh
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;700 /home/deploy/.ssh
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;600 /home/deploy/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;authorized_keys&lt;/code&gt; is the list of public keys allowed to log in as that user. &lt;code&gt;700&lt;/code&gt; and &lt;code&gt;600&lt;/code&gt; are not optional. SSH ignores a key file if other users can read it.&lt;/p&gt;

&lt;p&gt;Test from your PC. You should land in &lt;code&gt;/home/deploy&lt;/code&gt; with no password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/YOUR_APP_deploy deploy@YOUR_SERVER_IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Add the GitHub secrets
&lt;/h2&gt;

&lt;p&gt;In the repository: Settings, then Secrets and variables, then Actions, then New repository secret.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Secret&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SSH_HOST&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;YOUR_SERVER_IP&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SSH_USERNAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;deploy&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SSH_PRIVATE_KEY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The whole private file, including the &lt;code&gt;BEGIN&lt;/code&gt; and &lt;code&gt;END&lt;/code&gt; lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SSH_PORT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;22&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DEPLOY_PATH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/var/www/YOUR_DOMAIN&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Show the private key on your PC only, then paste it into GitHub. Use the file without &lt;code&gt;.pub&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/YOUR_APP_deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A small workflow you can put in &lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt; of that Laravel project. It builds the Vite files in GitHub, uploads the app, and does not upload &lt;code&gt;.env&lt;/code&gt; or &lt;code&gt;node_modules&lt;/code&gt;.&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="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy Laravel&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;shivammathur/setup-php@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;php-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8.3"&lt;/span&gt;
          &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;composer:v2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;20"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PHP dependencies and Vite build&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev&lt;/span&gt;
          &lt;span class="s"&gt;npm ci&lt;/span&gt;
          &lt;span class="s"&gt;npm run build&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/scp-action@v0.1.7&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_HOST }}&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_USERNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_PRIVATE_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_PORT || 22 }}&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.,!node_modules,!.env"&lt;/span&gt;
          &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DEPLOY_PATH }}&lt;/span&gt;
          &lt;span class="na"&gt;overwrite&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Migrate and refresh caches&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/ssh-action@v1.2.0&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_HOST }}&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_USERNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_PRIVATE_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_PORT || 22 }}&lt;/span&gt;
          &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;cd "${{ secrets.DEPLOY_PATH }}"&lt;/span&gt;
            &lt;span class="s"&gt;composer install --no-dev --optimize-autoloader --no-interaction&lt;/span&gt;
            &lt;span class="s"&gt;php artisan storage:link || true&lt;/span&gt;
            &lt;span class="s"&gt;php artisan migrate --force&lt;/span&gt;
            &lt;span class="s"&gt;php artisan config:cache&lt;/span&gt;
            &lt;span class="s"&gt;php artisan route:cache&lt;/span&gt;
            &lt;span class="s"&gt;php artisan view:cache&lt;/span&gt;
            &lt;span class="s"&gt;sudo systemctl reload php8.3-fpm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;deploy&lt;/code&gt; cannot run &lt;code&gt;sudo systemctl reload&lt;/code&gt; unless you allow that one command. If the reload line fails, SSH in as &lt;code&gt;YOUR_SUDO_USER&lt;/code&gt; and run &lt;code&gt;sudo systemctl reload php8.3-fpm&lt;/code&gt; yourself after the first deploy. PHP keeps the old cached config until that reload.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public/build&lt;/code&gt; must be in the upload. If GitHub skips &lt;code&gt;npm run build&lt;/code&gt;, Laravel pages that use &lt;code&gt;@vite&lt;/code&gt; return 500 with "Vite manifest not found."&lt;/p&gt;

&lt;h2&gt;
  
  
  9. First boot on the server
&lt;/h2&gt;

&lt;p&gt;After the first upload, as &lt;code&gt;deploy&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/YOUR_DOMAIN
composer &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-dev&lt;/span&gt; &lt;span class="nt"&gt;--optimize-autoloader&lt;/span&gt; &lt;span class="nt"&gt;--no-interaction&lt;/span&gt;
php artisan key:generate &lt;span class="nt"&gt;--force&lt;/span&gt;
php artisan migrate &lt;span class="nt"&gt;--force&lt;/span&gt;
php artisan storage:link
php artisan config:cache
php artisan route:cache
php artisan view:cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;key:generate&lt;/code&gt; writes &lt;code&gt;APP_KEY&lt;/code&gt;. Without it, every page is 500. Do not run it again on later deploys. A new key logs everybody out and can make old encrypted cookies unreadable.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;migrate --force&lt;/code&gt; creates tables, including &lt;code&gt;sessions&lt;/code&gt; if you use the database session driver. &lt;code&gt;--force&lt;/code&gt; is required because Laravel refuses to migrate when &lt;code&gt;APP_ENV=production&lt;/code&gt; unless you say so.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;storage:link&lt;/code&gt; makes &lt;code&gt;public/storage&lt;/code&gt; point at uploaded files. Skip the error if the link already exists.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;config:cache&lt;/code&gt; bakes &lt;code&gt;.env&lt;/code&gt; into one PHP file. After this, editing &lt;code&gt;.env&lt;/code&gt; does nothing until you run &lt;code&gt;config:cache&lt;/code&gt; again.&lt;/p&gt;

&lt;p&gt;PHP must be able to write logs and sessions. As &lt;code&gt;YOUR_SUDO_USER&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/www/YOUR_DOMAIN/storage/framework/&lt;span class="o"&gt;{&lt;/span&gt;cache/data,sessions,views&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /var/www/YOUR_DOMAIN/storage/logs &lt;span class="se"&gt;\&lt;/span&gt;
  /var/www/YOUR_DOMAIN/bootstrap/cache
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; deploy:www-data /var/www/YOUR_DOMAIN/storage /var/www/YOUR_DOMAIN/bootstrap/cache
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; ug+rwX /var/www/YOUR_DOMAIN/storage /var/www/YOUR_DOMAIN/bootstrap/cache
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload php8.3-fpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;www-data&lt;/code&gt; is the PHP user. The group write bit is what lets PHP save sessions and log a 500 instead of dying with &lt;code&gt;Permission denied&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Confirm the site
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;https://YOUR_DOMAIN/&lt;/code&gt; and one API URL, for example &lt;code&gt;https://YOUR_DOMAIN/api/user&lt;/code&gt; or whatever your &lt;code&gt;routes/api.php&lt;/code&gt; exposes. A 401 on a protected API route is fine. It means Laravel answered. A 404 from Nginx, with no Laravel styling, means the request never reached &lt;code&gt;index.php&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the page is 500:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo grep&lt;/span&gt; &lt;span class="s2"&gt;"production.ERROR"&lt;/span&gt; /var/www/YOUR_DOMAIN/storage/logs/laravel.log | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first &lt;code&gt;production.ERROR&lt;/code&gt; line is the cause. The long stack under it is not.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What the log says&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;No application encryption key&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;php artisan key:generate --force&lt;/code&gt;, then &lt;code&gt;config:cache&lt;/code&gt;, then reload PHP-FPM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;no such table: sessions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;php artisan migrate --force&lt;/code&gt;, or set &lt;code&gt;SESSION_DRIVER=file&lt;/code&gt; and cache config again&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Permission denied&lt;/code&gt; under &lt;code&gt;storage/&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Repeat the &lt;code&gt;chown&lt;/code&gt; and &lt;code&gt;chmod&lt;/code&gt; in step 9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Vite manifest not found&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;npm run build&lt;/code&gt; in GitHub (or on the server) so &lt;code&gt;public/build/manifest.json&lt;/code&gt; exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Access denied for user&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;DB_USERNAME&lt;/code&gt;, &lt;code&gt;DB_PASSWORD&lt;/code&gt;, and &lt;code&gt;DB_HOST=127.0.0.1&lt;/code&gt; must match the MySQL user from step 4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;After any &lt;code&gt;.env&lt;/code&gt; change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/YOUR_DOMAIN
php artisan config:cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then as the sudo user: &lt;code&gt;sudo systemctl reload php8.3-fpm&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Prepare the server before GitHub deploys. The order is: PHP, Composer, Nginx, and MySQL, a &lt;code&gt;deploy&lt;/code&gt; user, a folder that user owns, a MySQL user at &lt;code&gt;127.0.0.1&lt;/code&gt;, one &lt;code&gt;.env&lt;/code&gt;, Certbot, an SSH key, then a push.&lt;/p&gt;

&lt;p&gt;Blade pages and &lt;code&gt;/api&lt;/code&gt; are the same app. Nginx sends both to &lt;code&gt;public/index.php&lt;/code&gt;. You do not run a second process and you do not open an API port.&lt;/p&gt;

&lt;p&gt;When it fails, look here first:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;storage/logs/laravel.log&lt;/code&gt; for a 500 page. Read the &lt;code&gt;production.ERROR&lt;/code&gt; line.&lt;/li&gt;
&lt;li&gt;Confirm Nginx &lt;code&gt;root&lt;/code&gt; is &lt;code&gt;.../public&lt;/code&gt;, not the project root.&lt;/li&gt;
&lt;li&gt;Confirm &lt;code&gt;DB_HOST&lt;/code&gt; is &lt;code&gt;127.0.0.1&lt;/code&gt; and that &lt;code&gt;SELECT user, host FROM mysql.user&lt;/code&gt; shows that host.&lt;/li&gt;
&lt;li&gt;After an &lt;code&gt;.env&lt;/code&gt; edit, &lt;code&gt;php artisan config:cache&lt;/code&gt; and reload PHP-FPM.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not put the database password, &lt;code&gt;APP_KEY&lt;/code&gt;, or the private key in git. &lt;code&gt;deploy&lt;/code&gt; is the only account GitHub should log in as.&lt;/p&gt;

</description>
      <category>contabo</category>
      <category>github</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
