<?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: Dhananjay Haridas</title>
    <description>The latest articles on DEV Community by Dhananjay Haridas (@dhananjayharidas).</description>
    <link>https://dev.to/dhananjayharidas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F797506%2Ff827fa8b-3fe8-48aa-a327-df252a7c437b.png</url>
      <title>DEV Community: Dhananjay Haridas</title>
      <link>https://dev.to/dhananjayharidas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dhananjayharidas"/>
    <language>en</language>
    <item>
      <title>What is GitHub CLI?</title>
      <dc:creator>Dhananjay Haridas</dc:creator>
      <pubDate>Wed, 03 Jun 2026 12:15:29 +0000</pubDate>
      <link>https://dev.to/dhananjayharidas/what-is-github-cli-165b</link>
      <guid>https://dev.to/dhananjayharidas/what-is-github-cli-165b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Most developers interact with GitHub through a web browser. We open GitHub, create repositories, review pull requests, manage issues, and create releases through the website.&lt;/p&gt;

&lt;p&gt;But what if you could perform all those actions directly from your terminal?&lt;/p&gt;

&lt;p&gt;That is exactly what &lt;strong&gt;GitHub CLI&lt;/strong&gt;, commonly known as &lt;strong&gt;&lt;code&gt;gh&lt;/code&gt;&lt;/strong&gt;, allows you to do.&lt;/p&gt;

&lt;p&gt;GitHub CLI is an official command-line tool developed by GitHub that enables developers to work with GitHub without constantly switching between their code editor, terminal, and browser.&lt;/p&gt;

&lt;p&gt;By the end of this guide, you will understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What GitHub CLI is&lt;/li&gt;
&lt;li&gt;Why it exists&lt;/li&gt;
&lt;li&gt;How to install it&lt;/li&gt;
&lt;li&gt;How authentication works&lt;/li&gt;
&lt;li&gt;Common commands every developer should know&lt;/li&gt;
&lt;li&gt;Real-world workflows&lt;/li&gt;
&lt;li&gt;Best practices and tips&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  What is GitHub CLI?
&lt;/h1&gt;

&lt;p&gt;GitHub CLI is a command-line application that lets you interact with GitHub from your terminal.&lt;/p&gt;

&lt;p&gt;Instead of visiting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and clicking through menus, you can perform GitHub operations using commands.&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 shell"&gt;&lt;code&gt;gh repo create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;creates a repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;creates a pull request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh issue create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;creates an issue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh release create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;creates a release.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Was GitHub CLI Created?
&lt;/h1&gt;

&lt;p&gt;Before GitHub CLI existed, developers typically had three options:&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1: Use the GitHub Website
&lt;/h3&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to understand&lt;/li&gt;
&lt;li&gt;Visual interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constant context switching&lt;/li&gt;
&lt;li&gt;Slower for repetitive tasks&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Option 2: Use Git Commands
&lt;/h3&gt;

&lt;p&gt;Git commands help manage source control:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit
git push
git pull
git branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, Git itself does not manage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pull Requests&lt;/li&gt;
&lt;li&gt;Issues&lt;/li&gt;
&lt;li&gt;Releases&lt;/li&gt;
&lt;li&gt;Discussions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are GitHub features.&lt;/p&gt;




&lt;h3&gt;
  
  
  Option 3: Use GitHub APIs
&lt;/h3&gt;

&lt;p&gt;GitHub provides APIs.&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 shell"&gt;&lt;code&gt;curl &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer TOKEN"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://api.github.com/repos/user/project/issues
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works but can become complex.&lt;/p&gt;




&lt;p&gt;GitHub CLI bridges this gap.&lt;/p&gt;

&lt;p&gt;It provides a simple developer-friendly interface over GitHub APIs.&lt;/p&gt;




&lt;h1&gt;
  
  
  Git vs GitHub CLI
&lt;/h1&gt;

&lt;p&gt;Many beginners confuse Git and GitHub CLI.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Git&lt;/th&gt;
&lt;th&gt;GitHub CLI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Version control system&lt;/td&gt;
&lt;td&gt;GitHub management tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works locally&lt;/td&gt;
&lt;td&gt;Communicates with GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gh pr create&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gh issue create&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git merge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gh release create&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Think of it 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;Git = Manage code history

GitHub CLI = Manage GitHub platform features
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Installing GitHub CLI
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Ubuntu
&lt;/h2&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="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;gh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh version 2.70.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  macOS
&lt;/h2&gt;

&lt;p&gt;Using Homebrew:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;gh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Windows
&lt;/h2&gt;

&lt;p&gt;Using Winget:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;winget&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;GitHub.cli&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  First-Time Authentication
&lt;/h1&gt;

&lt;p&gt;After installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see options 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;? What account do you want to log into?
GitHub.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login with browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub CLI will generate a code.&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;First copy your one-time code:
ABCD-EFGH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the browser and authenticate.&lt;/p&gt;




&lt;h1&gt;
  
  
  Check Authentication Status
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh auth status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;Logged in to github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Creating a Repository
&lt;/h1&gt;

&lt;p&gt;Create a repository directly from the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh repo create my-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interactive mode will ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Public or Private?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choose your preference.&lt;/p&gt;




&lt;h1&gt;
  
  
  Cloning a Repository
&lt;/h1&gt;

&lt;p&gt;Traditional Git:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/user/project.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh repo clone user/project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh repo clone octocat/demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Viewing Repository Information
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh repo view
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Repository:
user/project

Description:
My project

Stars:
120
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Creating Issues
&lt;/h1&gt;

&lt;p&gt;Issues are used to track bugs and feature requests.&lt;/p&gt;

&lt;p&gt;Create one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh issue create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interactive prompts appear.&lt;/p&gt;

&lt;p&gt;You can also provide everything directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh issue create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"Login Bug"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Users cannot log in"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Listing Issues
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh issue list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;#23 Login Bug
#24 Add Dark Mode
#25 Improve Performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Viewing a Specific Issue
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh issue view 23
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Creating Pull Requests
&lt;/h1&gt;

&lt;p&gt;One of the most powerful features.&lt;/p&gt;

&lt;p&gt;After pushing a branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push origin feature/login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a PR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub CLI asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Title?
Description?
Base branch?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then creates the pull request.&lt;/p&gt;




&lt;h1&gt;
  
  
  Listing Pull Requests
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;#45 Add Login Feature
#46 Fix Database Error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Viewing Pull Requests
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;view 45
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Checking Out a Pull Request
&lt;/h1&gt;

&lt;p&gt;Instead of manually fetching branches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;checkout 45
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This automatically switches to the PR branch.&lt;/p&gt;




&lt;h1&gt;
  
  
  Reviewing Pull Requests
&lt;/h1&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;review 45 &lt;span class="nt"&gt;--approve&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Request changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;review 45 &lt;span class="nt"&gt;--request-changes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;review 45 &lt;span class="nt"&gt;--comment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Merging Pull Requests
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;merge 45
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;merge 45 &lt;span class="nt"&gt;--merge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;merge 45 &lt;span class="nt"&gt;--squash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;merge 45 &lt;span class="nt"&gt;--rebase&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Working with Releases
&lt;/h1&gt;

&lt;p&gt;A release is a published version of software.&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;v1.0.0
v1.1.0
v2.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Create a Release
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh release create v1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Add Release Notes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh release create v1.0.0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--notes&lt;/span&gt; &lt;span class="s2"&gt;"Initial release"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Upload Files
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh release create v1.0.0 &lt;span class="se"&gt;\&lt;/span&gt;
  dist/app.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is likely what happened in your project.&lt;/p&gt;

&lt;p&gt;Your Makefile probably executes something similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh release create &lt;span class="se"&gt;\&lt;/span&gt;
  v1.0.0 &lt;span class="se"&gt;\&lt;/span&gt;
  dist/registry-data-v1.0.0.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without GitHub CLI installed, that step fails.&lt;/p&gt;




&lt;h1&gt;
  
  
  Viewing Releases
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh release list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;v1.0.0
v1.1.0
v2.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Download Release Assets
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh release download v1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Working with GitHub Actions
&lt;/h1&gt;

&lt;p&gt;View workflows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh workflow list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;View workflow runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh run list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Inspect a run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh run view
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Watch live logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh run watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Working with Gists
&lt;/h1&gt;

&lt;p&gt;Create a gist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh gist create notes.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;List gists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh gist list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Useful Commands Every Developer Should Know
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh auth login
gh auth status
gh auth &lt;span class="nb"&gt;logout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Repositories
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh repo create
gh repo clone
gh repo view
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Issues
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh issue create
gh issue list
gh issue view
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Pull Requests
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create
gh &lt;span class="nb"&gt;pr &lt;/span&gt;list
gh &lt;span class="nb"&gt;pr &lt;/span&gt;view
gh &lt;span class="nb"&gt;pr &lt;/span&gt;checkout
gh &lt;span class="nb"&gt;pr &lt;/span&gt;merge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Releases
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh release create
gh release list
gh release view
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Real-World Example Workflow
&lt;/h1&gt;

&lt;p&gt;Imagine you are implementing a feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1
&lt;/h3&gt;

&lt;p&gt;Create a branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 2
&lt;/h3&gt;

&lt;p&gt;Write code.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 3
&lt;/h3&gt;

&lt;p&gt;Commit changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add payment support"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 4
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push origin feature/payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 5
&lt;/h3&gt;

&lt;p&gt;Create PR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 6
&lt;/h3&gt;

&lt;p&gt;Review PR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;view
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 7
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;merge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 8
&lt;/h3&gt;

&lt;p&gt;Create Release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh release create v1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entire workflow completed without opening GitHub in a browser.&lt;/p&gt;




&lt;h1&gt;
  
  
  Advantages of GitHub CLI
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Faster Workflow
&lt;/h3&gt;

&lt;p&gt;No browser switching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automation Friendly
&lt;/h3&gt;

&lt;p&gt;Perfect for scripts and CI/CD pipelines.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consistent Interface
&lt;/h3&gt;

&lt;p&gt;Everything from one terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer Productivity
&lt;/h3&gt;

&lt;p&gt;Reduces repetitive work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Official Tool
&lt;/h3&gt;

&lt;p&gt;Maintained by GitHub.&lt;/p&gt;




&lt;h1&gt;
  
  
  When Should You Use GitHub CLI?
&lt;/h1&gt;

&lt;p&gt;Use GitHub CLI if you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work with GitHub daily&lt;/li&gt;
&lt;li&gt;Create pull requests frequently&lt;/li&gt;
&lt;li&gt;Manage releases&lt;/li&gt;
&lt;li&gt;Handle issues regularly&lt;/li&gt;
&lt;li&gt;Build automation scripts&lt;/li&gt;
&lt;li&gt;Work in DevOps or platform engineering&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Common Beginner Mistakes
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Forgetting Authentication
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;must be completed first.&lt;/p&gt;




&lt;h3&gt;
  
  
  Confusing Git with GitHub CLI
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Git manages code history.

GitHub CLI manages GitHub features.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Missing Permissions
&lt;/h3&gt;

&lt;p&gt;Your GitHub account must have permissions for the repository.&lt;/p&gt;




&lt;h3&gt;
  
  
  Not Updating GitHub CLI
&lt;/h3&gt;

&lt;p&gt;Keep it updated:&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="nb"&gt;sudo &lt;/span&gt;apt upgrade gh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;GitHub CLI (&lt;code&gt;gh&lt;/code&gt;) is GitHub's official command-line tool that allows developers to manage repositories, issues, pull requests, releases, workflows, and many other GitHub features directly from the terminal.&lt;/p&gt;

&lt;p&gt;For a junior developer, learning GitHub CLI provides several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster development workflows&lt;/li&gt;
&lt;li&gt;Less dependence on the browser&lt;/li&gt;
&lt;li&gt;Easier automation&lt;/li&gt;
&lt;li&gt;Better understanding of GitHub operations&lt;/li&gt;
&lt;li&gt;Improved productivity in professional software teams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're already comfortable with commands like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add
git commit
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then learning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create
gh issue create
gh release create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is the next natural step toward becoming a more efficient developer.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>github</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Fuzzy Text Search in PostgreSQL: How Trigrams Make Computers "Almost Right"</title>
      <dc:creator>Dhananjay Haridas</dc:creator>
      <pubDate>Wed, 03 Jun 2026 08:39:43 +0000</pubDate>
      <link>https://dev.to/dhananjayharidas/fuzzy-text-search-in-postgresql-how-trigrams-make-computers-almost-right-2hmk</link>
      <guid>https://dev.to/dhananjayharidas/fuzzy-text-search-in-postgresql-how-trigrams-make-computers-almost-right-2hmk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A deep dive into one of the most clever tricks in database engineering - explained so simply, your grandmother could follow along.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Problem: Computers Are Too Exact
&lt;/h2&gt;

&lt;p&gt;Imagine you're searching for a restaurant called &lt;strong&gt;"Maharaja Palace"&lt;/strong&gt; on an app. You type &lt;em&gt;"Maharja Palce"&lt;/em&gt; - two small typos. A traditional search engine looks at your input and says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"No results found."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Zero. Nothing. Because the text doesn't &lt;strong&gt;exactly&lt;/strong&gt; match.&lt;/p&gt;

&lt;p&gt;This is the fundamental problem with how computers search for text. They compare strings character by character, and if even one letter is out of place, the match fails. Humans, on the other hand, are remarkably good at understanding that "Maharja" probably means "Maharaja". We do it instinctively, without even thinking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fuzzy search&lt;/strong&gt; is the art of teaching computers to think a little more like humans - to find things that are &lt;em&gt;close enough&lt;/em&gt;, not just &lt;em&gt;exactly right&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And in PostgreSQL, the most powerful tool for this is called &lt;strong&gt;Trigram Search&lt;/strong&gt;, powered by an extension called &lt;code&gt;pg_trgm&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 1: What Is a Trigram? (The Building Block of Everything)
&lt;/h2&gt;

&lt;p&gt;Before we dive into how PostgreSQL searches, we need to understand one simple concept: the &lt;strong&gt;trigram&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;trigram&lt;/strong&gt; is just a group of &lt;strong&gt;3 consecutive characters&lt;/strong&gt; from a word.&lt;/p&gt;

&lt;p&gt;That's it. Three letters in a row.&lt;/p&gt;

&lt;p&gt;Let's break the word &lt;strong&gt;"cat"&lt;/strong&gt; into trigrams:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Word: "cat"
PostgreSQL pads the word with spaces for edge handling: "  cat  "

Trigrams:
  "  c"
  " ca"
  "cat"
  "at "
  "t  "
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 PostgreSQL secretly adds two spaces before and one space after every word. This is to give the beginning and end of words their own identity, so "cat" and "concatenate" don't blur together.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's try a longer word: &lt;strong&gt;"elephant"&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Word: "  elephant "

Trigrams:
  "  e"
  " el"
  "ele"
  "lep"
  "eph"
  "pha"
  "han"
  "ant"
  "nt "
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every word gets chopped into these little 3-character windows, sliding one character at a time across the word from left to right.&lt;/p&gt;

&lt;p&gt;Think of it like a &lt;strong&gt;magnifying glass&lt;/strong&gt; that's 3 characters wide, slowly sliding across a word and taking a snapshot at every position.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 2: Why Trigrams? Why Not 2 or 4 Letters?
&lt;/h2&gt;

&lt;p&gt;This is a fair question. Why exactly three?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bigrams (2 letters):&lt;/strong&gt; Too short. The bigram "ca" appears in "cat", "car", "can", "castle", "scar", "occasion"... it's so common it doesn't carry much meaning. Matching would produce too many false positives.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;4-grams or longer:&lt;/strong&gt; Too specific. A 4-gram like "elep" only really appears in "elephant" and close relatives. If you make a typo in that 4-gram, you lose the match entirely. Too brittle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Trigrams (3 letters):&lt;/strong&gt; The sweet spot. Common enough to appear across related words, specific enough to carry meaning. A single typo only destroys a few trigrams, leaving most of the others intact to still find a match.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's the Goldilocks zone of string matching.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 3: The Magic - How Similarity Is Calculated
&lt;/h2&gt;

&lt;p&gt;Here's where the real cleverness lives.&lt;/p&gt;

&lt;p&gt;Once every word is broken into trigrams, PostgreSQL measures &lt;strong&gt;how similar two words are&lt;/strong&gt; by counting how many trigrams they &lt;em&gt;share&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The formula is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Similarity = (Number of shared trigrams) / (Total unique trigrams across both words)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives a number between &lt;strong&gt;0&lt;/strong&gt; (completely different) and &lt;strong&gt;1&lt;/strong&gt; (identical).&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's work through a real example
&lt;/h3&gt;

&lt;p&gt;Say we're comparing &lt;strong&gt;"night"&lt;/strong&gt; and &lt;strong&gt;"knight"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Generate trigrams for "night"&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"  n", " ni", "nig", "igh", "ght", "ht "
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ 6 trigrams&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Generate trigrams for "knight"&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"  k", " kn", "kni", "nig", "igh", "ght", "ht "
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ 7 trigrams&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Find the shared trigrams&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Shared: "nig", "igh", "ght", "ht "
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ 4 shared trigrams&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Calculate similarity&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Total unique trigrams = 6 + 7 - 4 = 9   (subtract shared ones to avoid counting them twice)
Shared = 4

Similarity = 4 / 9 = 0.44
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So "night" and "knight" are about &lt;strong&gt;44% similar&lt;/strong&gt; according to trigrams. That seems low - they sound the same! But trigrams are measuring &lt;em&gt;character patterns&lt;/em&gt;, not pronunciation. The extra "kn" at the start of "knight" introduces several new unique trigrams that "night" doesn't have.&lt;/p&gt;

&lt;h3&gt;
  
  
  Now let's try a typo: "niight" vs "night"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Trigrams for "niight":&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"  n", " ni", "nii", "iig", "igh", "ght", "ht "
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Trigrams for "night":&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"  n", " ni", "nig", "igh", "ght", "ht "
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Shared:&lt;/strong&gt; &lt;code&gt;"  n"&lt;/code&gt;, &lt;code&gt;" ni"&lt;/code&gt;, &lt;code&gt;"igh"&lt;/code&gt;, &lt;code&gt;"ght"&lt;/code&gt;, &lt;code&gt;"ht "&lt;/code&gt; → 5 shared&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Total unique:&lt;/strong&gt; 7 + 6 - 5 = 8&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Similarity = 5/8 = 0.625&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Despite the typo ("niight"), the similarity is still &lt;strong&gt;62.5%&lt;/strong&gt; - high enough that a search would still find the match. This is the magic of trigrams.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 4: The Threshold - Deciding What "Close Enough" Means
&lt;/h2&gt;

&lt;p&gt;Now that we can calculate similarity as a number, we need to decide: &lt;strong&gt;how similar is similar enough?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL uses a default threshold of &lt;strong&gt;0.3&lt;/strong&gt; (30%). If two strings share at least 30% of their trigrams, they're considered a match.&lt;/p&gt;

&lt;p&gt;You can think of it like a teacher grading papers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Score ≥ 0.3 → Pass (it's a match)&lt;/li&gt;
&lt;li&gt;Score &amp;lt; 0.3 → Fail (not a match)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can adjust this threshold depending on how strict or lenient you want your search to be:&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="c1"&gt;-- Make it stricter (only very close matches)&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;pg_trgm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;similarity_threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Make it more lenient (catch more distant matches, but more noise)&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;pg_trgm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;similarity_threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Practical guidance:&lt;/strong&gt;&lt;br&gt;
| Threshold | Best For |&lt;br&gt;
|-----------|----------|&lt;br&gt;
| 0.1 – 0.2 | Very forgiving search, names from other languages |&lt;br&gt;
| 0.3 | General purpose (default, works well most of the time) |&lt;br&gt;
| 0.5 | Names, product codes where near-exact match is needed |&lt;br&gt;
| 0.7+ | Almost exact matching only |&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 5: Under the Hood - How PostgreSQL Actually Executes the Search
&lt;/h2&gt;

&lt;p&gt;Understanding the math is one thing. But how does PostgreSQL actually &lt;em&gt;run&lt;/em&gt; this efficiently when you have millions of rows? Recalculating trigrams for every row on every query would be painfully slow.&lt;/p&gt;

&lt;p&gt;The answer is: &lt;strong&gt;the GIN Index&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is a GIN Index?
&lt;/h3&gt;

&lt;p&gt;GIN stands for &lt;strong&gt;Generalized Inverted Index&lt;/strong&gt;. The name sounds intimidating, but the concept is simple.&lt;/p&gt;

&lt;p&gt;Think of it like the &lt;strong&gt;index at the back of a book&lt;/strong&gt;. Instead of reading every page to find where "photosynthesis" is mentioned, you flip to the back, find "photosynthesis" alphabetically, and it tells you exactly which pages contain it.&lt;/p&gt;

&lt;p&gt;A GIN index does the same thing for trigrams:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GIN Index Structure (simplified):

" ca" → [row 5, row 12, row 89, row 203]
" co" → [row 3, row 7, row 44]
"cat" → [row 5, row 89]
"cof" → [row 3]
"ofe" → [row 3]
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For every possible trigram, the index stores a list of which rows contain that trigram. When you search for "coffee", PostgreSQL:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Breaks "coffee" into its trigrams: &lt;code&gt;" co"&lt;/code&gt;, &lt;code&gt;"cof"&lt;/code&gt;, &lt;code&gt;"off"&lt;/code&gt;, &lt;code&gt;"ffe"&lt;/code&gt;, &lt;code&gt;"fee"&lt;/code&gt;, &lt;code&gt;"ee "&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Looks up each trigram in the GIN index&lt;/li&gt;
&lt;li&gt;Finds rows that contain &lt;em&gt;several&lt;/em&gt; of these trigrams (intersection)&lt;/li&gt;
&lt;li&gt;Calculates the exact similarity score only for those candidate rows&lt;/li&gt;
&lt;li&gt;Returns results above the threshold&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of scanning millions of rows, it scans a short list of candidates. This is what makes trigram search &lt;strong&gt;fast&lt;/strong&gt; - often hundreds of times faster than a brute-force scan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visualizing the Query Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;Your&lt;/span&gt; &lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;"SELECT * WHERE name % 'cofee'"&lt;/span&gt;
                    &lt;span class="err"&gt;│&lt;/span&gt;
                    &lt;span class="err"&gt;▼&lt;/span&gt;
         &lt;span class="n"&gt;Break&lt;/span&gt; &lt;span class="s1"&gt;'cofee'&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="n"&gt;trigrams&lt;/span&gt;
         &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;" co"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"cof"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"ofe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"fee"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"ee "&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="err"&gt;│&lt;/span&gt;
                    &lt;span class="err"&gt;▼&lt;/span&gt;
         &lt;span class="n"&gt;Look&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="k"&gt;each&lt;/span&gt; &lt;span class="n"&gt;trigram&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;GIN&lt;/span&gt; &lt;span class="k"&gt;index&lt;/span&gt;
         &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Candidate&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;89&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="err"&gt;│&lt;/span&gt;
                    &lt;span class="err"&gt;▼&lt;/span&gt;
         &lt;span class="n"&gt;Calculate&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;each&lt;/span&gt; &lt;span class="n"&gt;candidate&lt;/span&gt;
         &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;Row&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;71&lt;/span&gt; &lt;span class="err"&gt;✓&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;above&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;Row&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="err"&gt;✗&lt;/span&gt;
         &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;Row&lt;/span&gt; &lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;65&lt;/span&gt; &lt;span class="err"&gt;✓&lt;/span&gt;
         &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;Row&lt;/span&gt; &lt;span class="mi"&gt;89&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt; &lt;span class="err"&gt;✗&lt;/span&gt;
         &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;Row&lt;/span&gt; &lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="err"&gt;✓&lt;/span&gt;
                    &lt;span class="err"&gt;│&lt;/span&gt;
                    &lt;span class="err"&gt;▼&lt;/span&gt;
         &lt;span class="k"&gt;Return&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;102&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;ordered&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without the GIN index, step 2 would require checking every row. With it, only a handful of candidates get the expensive similarity calculation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 6: Setting It Up in PostgreSQL
&lt;/h2&gt;

&lt;p&gt;Enough theory - here's how you actually use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Enable the Extension
&lt;/h3&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="n"&gt;EXTENSION&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;pg_trgm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a one-time setup per database. The extension comes bundled with PostgreSQL - no installation needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create Your Table and Index
&lt;/h3&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;TABLE&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Create a GIN index on the name column&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_products_name_trgm&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
    &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="n"&gt;GIN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;gin_trgm_ops&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;gin_trgm_ops&lt;/code&gt; part tells PostgreSQL: &lt;em&gt;"use trigram logic for this index"&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Query Using Similarity
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- The % operator: returns rows above the similarity threshold&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s1"&gt;'cofee maker'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- The similarity() function: returns the score, lets you sort by closeness&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'cofee maker'&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;score&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s1"&gt;'cofee maker'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sample output:&lt;/strong&gt;&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="n"&gt;name&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;
&lt;span class="c1"&gt;-------------------+-------&lt;/span&gt;
&lt;span class="n"&gt;Coffee&lt;/span&gt; &lt;span class="n"&gt;Maker&lt;/span&gt; &lt;span class="n"&gt;Pro&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;
&lt;span class="n"&gt;Coffee&lt;/span&gt; &lt;span class="n"&gt;Maker&lt;/span&gt; &lt;span class="n"&gt;Mini&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;78&lt;/span&gt;
&lt;span class="n"&gt;Coffee&lt;/span&gt; &lt;span class="n"&gt;Mug&lt;/span&gt; &lt;span class="k"&gt;Set&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Tune the Threshold (Optional)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- See the current threshold&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;pg_trgm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;similarity_threshold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Change it for this session&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;pg_trgm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;similarity_threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Part 7: Real-World Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Search Autocomplete / "Did you mean?"
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- User typed "postgress" - find the closest match&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'postgress'&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;score&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;technologies&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s1"&gt;'postgress'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Deduplication - Finding Near-Duplicate Records
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Find customer records that might be the same person&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&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;score&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Product Search with Typo Tolerance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Search even with misspellings&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&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;relevance&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
   &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;relevance&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Combining with Full-Text Search for Best Results
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Use full-text search for speed + trigrams for typo tolerance&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ts_rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&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;text_rank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'databse'&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;fuzzy_rank&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;plainto_tsquery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'english'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'database'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;tsv&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;
   &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s1"&gt;'databse'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ts_rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'databse'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Part 8: The &lt;code&gt;word_similarity&lt;/code&gt; and &lt;code&gt;strict_word_similarity&lt;/code&gt; Functions
&lt;/h2&gt;

&lt;p&gt;PostgreSQL's &lt;code&gt;pg_trgm&lt;/code&gt; also provides two variants of the similarity function that handle &lt;strong&gt;multi-word strings&lt;/strong&gt; differently.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;similarity(a, b)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compares the full strings as a whole&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;word_similarity(a, b)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Checks if &lt;code&gt;a&lt;/code&gt; is similar to &lt;em&gt;any word&lt;/em&gt; in &lt;code&gt;b&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;strict_word_similarity(a, b)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Like &lt;code&gt;word_similarity&lt;/code&gt; but requires whole-word boundaries&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&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="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'word'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'two words'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;-- Returns: 0.18 (compares full strings)&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;word_similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'word'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'two words'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;-- Returns: 0.8 (finds that 'word' closely matches 'words')&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is invaluable when users search for a single product word inside a longer product name.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 9: Performance Tips
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Always Create the GIN Index Before Querying Large Tables
&lt;/h3&gt;

&lt;p&gt;Without the index, PostgreSQL does a full sequential scan - checking every row. On a table with 10 million rows, this can take minutes. With the index, the same query can complete in milliseconds.&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="c1"&gt;-- Check if your query is using the index&lt;/span&gt;
&lt;span class="k"&gt;EXPLAIN&lt;/span&gt; &lt;span class="k"&gt;ANALYZE&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s1"&gt;'laptop'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for &lt;code&gt;Index Scan using idx_products_name_trgm&lt;/code&gt; in the output. If you see &lt;code&gt;Seq Scan&lt;/code&gt; instead, your index isn't being used - check that it was created correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Index Maintenance
&lt;/h3&gt;

&lt;p&gt;GIN indexes can become bloated over time with many inserts and updates. Periodically run:&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;VACUUM&lt;/span&gt; &lt;span class="k"&gt;ANALYZE&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Consider a &lt;code&gt;GIST&lt;/code&gt; Index for Certain Workloads
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Alternative index type&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_products_name_gist&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
    &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="n"&gt;GIST&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;gist_trgm_ops&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Index Type&lt;/th&gt;
&lt;th&gt;Build Speed&lt;/th&gt;
&lt;th&gt;Query Speed&lt;/th&gt;
&lt;th&gt;Update Speed&lt;/th&gt;
&lt;th&gt;Choose When&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GIN&lt;/td&gt;
&lt;td&gt;Slower&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Slower&lt;/td&gt;
&lt;td&gt;Read-heavy workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GiST&lt;/td&gt;
&lt;td&gt;Faster&lt;/td&gt;
&lt;td&gt;Slower&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Write-heavy workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Part 10: Limitations - When Trigrams Don't Work Well
&lt;/h2&gt;

&lt;p&gt;Trigrams are powerful but not magic. They struggle in a few situations:&lt;/p&gt;

&lt;h3&gt;
  
  
  Short Strings (Less Than 3 Characters)
&lt;/h3&gt;

&lt;p&gt;A 1 or 2 character string can't form a meaningful set of trigrams. Searching for "AI" or "DB" will produce poor results.&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="c1"&gt;-- Workaround: Fall back to ILIKE for very short queries&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt;
    &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="k"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'AI'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;ILIKE&lt;/span&gt; &lt;span class="s1"&gt;'%AI%'&lt;/span&gt;
    &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s1"&gt;'AI'&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Very Different Languages
&lt;/h3&gt;

&lt;p&gt;Trigrams work on character patterns. For languages with different scripts (Arabic, Chinese, Thai), the trigram approach still works but may need different tokenization strategies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phonetic Similarity
&lt;/h3&gt;

&lt;p&gt;Trigrams match &lt;em&gt;visual&lt;/em&gt; similarity, not &lt;em&gt;sound&lt;/em&gt; similarity. "Night" and "knight" sound identical but have low trigram similarity because they look different. For phonetic matching, consider the &lt;code&gt;fuzzystrmatch&lt;/code&gt; extension with &lt;code&gt;soundex&lt;/code&gt; or &lt;code&gt;metaphone&lt;/code&gt;.&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="n"&gt;EXTENSION&lt;/span&gt; &lt;span class="n"&gt;fuzzystrmatch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;names&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;metaphone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;metaphone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'knight'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;-- This would match "night" and "knight"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Summary: The Trigram Story in One Paragraph
&lt;/h2&gt;

&lt;p&gt;Every word in your database gets sliced into overlapping 3-character chunks called trigrams. These trigrams are stored in a GIN index - like a giant lookup table mapping each trigram to the rows containing it. When you search for a word, PostgreSQL slices &lt;em&gt;that&lt;/em&gt; word into trigrams too, quickly finds candidate rows via the index, then calculates a similarity score (0 to 1) based on how many trigrams the two words share. If that score passes a threshold (default 0.3), it's considered a match. The result: fast, typo-tolerant, human-friendly search - baked right into your database, no external search engine required.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference Cheat Sheet
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Setup&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;EXTENSION&lt;/span&gt; &lt;span class="n"&gt;pg_trgm&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;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="n"&gt;GIN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;column&lt;/span&gt; &lt;span class="n"&gt;gin_trgm_ops&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Basic search&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;column&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s1"&gt;'search term'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- With score&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;column&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'search term'&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;score&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;column&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s1"&gt;'search term'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Adjust threshold&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;pg_trgm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;similarity_threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Word-level similarity&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;word_similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'search'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'long string with search inside'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Check index usage&lt;/span&gt;
&lt;span class="k"&gt;EXPLAIN&lt;/span&gt; &lt;span class="k"&gt;ANALYZE&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;column&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s1"&gt;'term'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;em&gt;Fuzzy search is one of those features that, once you add it to your application, users can't imagine living without. That tolerant, forgiving search experience - the one that doesn't punish you for a stray keystroke - is powered by these elegant little 3-character windows sliding across your data, quietly doing the math.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>database</category>
      <category>postgres</category>
      <category>sql</category>
    </item>
    <item>
      <title>Scaling Celery-Based Application in Production</title>
      <dc:creator>Dhananjay Haridas</dc:creator>
      <pubDate>Sun, 26 May 2024 14:19:23 +0000</pubDate>
      <link>https://dev.to/dhananjayharidas/scaling-celery-based-application-in-production-jak</link>
      <guid>https://dev.to/dhananjayharidas/scaling-celery-based-application-in-production-jak</guid>
      <description>&lt;p&gt;This documentation covers how to scale a Celery-based application for document extraction and comparison using FastAPI, Celery, and Redis. The guide includes steps for task splitting, configuring task dependencies, and scaling individual tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Task Definitions&lt;/li&gt;
&lt;li&gt;Orchestrating Tasks with Parallel Processing&lt;/li&gt;
&lt;li&gt;FastAPI Integration&lt;/li&gt;
&lt;li&gt;Scaling Celery Workers&lt;/li&gt;
&lt;li&gt;Using Dedicated Queues for Each Task Type&lt;/li&gt;
&lt;li&gt;Autoscaling&lt;/li&gt;
&lt;li&gt;Distributed Task Execution&lt;/li&gt;
&lt;li&gt;Monitoring and Management&lt;/li&gt;
&lt;li&gt;Load Balancing and High Availability&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This guide provides a detailed explanation of how to scale a Celery-based application that performs document extraction and comparison. It covers breaking down the tasks, orchestrating them for parallel processing, and scaling the application to handle increased loads in a production environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task Definitions
&lt;/h2&gt;

&lt;p&gt;Define the tasks for fetching, extracting, and comparing documents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# tasks.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;celery_config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;celery_app&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;

&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@celery_app.task&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_documents_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blob_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blob_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Replace with your actual fetch logic
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;  &lt;span class="c1"&gt;# Assume this returns a list of document paths or contents
&lt;/span&gt;    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&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;Error fetching documents: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&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="k"&gt;raise&lt;/span&gt;

&lt;span class="nd"&gt;@celery_app.task&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_data_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;extracted_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extract_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Replace with your actual extraction logic
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;extracted_data&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&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;Error extracting data: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&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="k"&gt;raise&lt;/span&gt;

&lt;span class="nd"&gt;@celery_app.task&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;compare_data_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extracted_data_list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;comparison_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;compare_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extracted_data_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Replace with your actual comparison logic
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;comparison_results&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&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;Error comparing data: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&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="k"&gt;raise&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Orchestrating Tasks with Parallel Processing
&lt;/h2&gt;

&lt;p&gt;Use a combination of chains and groups to handle dependencies and parallel processing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py or workflow.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;celery&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;fetch_documents_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extract_data_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compare_data_task&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blob_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Step 1: Fetch documents
&lt;/span&gt;    &lt;span class="n"&gt;fetch_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fetch_documents_task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blob_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 2: Extract data from each document in parallel
&lt;/span&gt;    &lt;span class="n"&gt;extract_tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fetch_task&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extract_data_task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;fetch_task&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="c1"&gt;# Step 3: Compare the extracted data
&lt;/span&gt;    &lt;span class="n"&gt;compare_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;compare_data_task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Combine the workflow into a single chain
&lt;/span&gt;    &lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fetch_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extract_tasks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compare_task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply_async&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  FastAPI Integration
&lt;/h2&gt;

&lt;p&gt;Integrate the workflow with a FastAPI endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;process_documents&lt;/span&gt;  &lt;span class="c1"&gt;# Import your workflow function
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;celery_config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;celery_app&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/process/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_endpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blob_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;process_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blob_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;task_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/status/{task_id}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;celery_app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AsyncResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PENDING&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&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;Pending...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SUCCESS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&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;Completed&lt;/span&gt;&lt;span class="sh"&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;result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;FAILURE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&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;Failed&lt;/span&gt;&lt;span class="sh"&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;result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Scaling Celery Workers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Increasing the Number of Workers
&lt;/h3&gt;

&lt;p&gt;Start multiple Celery worker processes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To scale further, start more workers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4
celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Distributed Workers
&lt;/h3&gt;

&lt;p&gt;Run workers on different machines by pointing them to the same message broker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4 &lt;span class="nt"&gt;-Q&lt;/span&gt; fetch_queue
celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8 &lt;span class="nt"&gt;-Q&lt;/span&gt; extract_queue
celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2 &lt;span class="nt"&gt;-Q&lt;/span&gt; compare_queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using Dedicated Queues for Each Task Type
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Defining Queues
&lt;/h3&gt;

&lt;p&gt;Configure Celery to define multiple queues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# celery_config.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;celery&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Celery&lt;/span&gt;

&lt;span class="n"&gt;celery_app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Celery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tasks&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;broker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;redis://localhost:6379/0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;redis://localhost:6379/0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;celery_app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;task_queues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fetch_queue&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;routing_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fetch.#&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;extract_queue&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;routing_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;extract.#&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;compare_queue&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;routing_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;compare.#&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="n"&gt;celery_app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;task_routes&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;tasks.fetch_documents_task&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;queue&lt;/span&gt;&lt;span class="sh"&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;fetch_queue&lt;/span&gt;&lt;span class="sh"&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;routing_key&lt;/span&gt;&lt;span class="sh"&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;fetch.documents&lt;/span&gt;&lt;span class="sh"&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;tasks.extract_data_task&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;queue&lt;/span&gt;&lt;span class="sh"&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;extract_queue&lt;/span&gt;&lt;span class="sh"&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;routing_key&lt;/span&gt;&lt;span class="sh"&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;extract.data&lt;/span&gt;&lt;span class="sh"&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;tasks.compare_data_task&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;queue&lt;/span&gt;&lt;span class="sh"&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;compare_queue&lt;/span&gt;&lt;span class="sh"&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;routing_key&lt;/span&gt;&lt;span class="sh"&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;compare.data&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;h3&gt;
  
  
  Starting Workers for Specific Queues
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4 &lt;span class="nt"&gt;-Q&lt;/span&gt; fetch_queue
celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8 &lt;span class="nt"&gt;-Q&lt;/span&gt; extract_queue
celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2 &lt;span class="nt"&gt;-Q&lt;/span&gt; compare_queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Autoscaling
&lt;/h2&gt;

&lt;p&gt;Enable autoscaling to dynamically adjust the number of worker processes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--autoscale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10,3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--autoscale=10,3&lt;/code&gt;: Scales between 3 and 10 worker processes based on load.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Distributed Task Execution
&lt;/h2&gt;

&lt;p&gt;Distribute Celery workers across multiple machines:&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Machine 1 (Message Broker and Backend):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run Redis as your broker and backend.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Machine 2 (Worker Node):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start Celery workers:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4 &lt;span class="nt"&gt;-Q&lt;/span&gt; fetch_queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Machine 3 (Worker Node):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start Celery workers:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8 &lt;span class="nt"&gt;-Q&lt;/span&gt; extract_queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Machine 4 (Worker Node):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start Celery workers:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--concurrency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2 &lt;span class="nt"&gt;-Q&lt;/span&gt; compare_queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Monitoring and Management
&lt;/h2&gt;

&lt;p&gt;Use monitoring tools like Flower, Prometheus, and Grafana to monitor Celery tasks:&lt;/p&gt;

&lt;h3&gt;
  
  
  Flower
&lt;/h3&gt;

&lt;p&gt;Start Flower to monitor Celery workers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;celery &lt;span class="nt"&gt;-A&lt;/span&gt; celery_config flower
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Load Balancing and High Availability
&lt;/h2&gt;

&lt;p&gt;Implement load balancing for high availability and fault tolerance:&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Load Balancer Setup
&lt;/h3&gt;

&lt;p&gt;Use HAProxy or another load balancer to distribute requests across multiple Redis instances.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scale Workers:&lt;/strong&gt; Increase the number of Celery workers to handle more tasks concurrently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dedicated Queues:&lt;/strong&gt; Use different queues for different types of tasks and scale them independently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autoscaling:&lt;/strong&gt; Enable autoscaling to dynamically adjust the number of worker processes based on load.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distributed Execution:&lt;/strong&gt; Distribute workers across multiple machines to improve scalability and fault tolerance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring:&lt;/strong&gt; Use monitoring tools to keep track of the performance and health of your Celery workers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Balancing:&lt;/strong&gt; Implement load balancing for high availability and fault tolerance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By following these strategies, you can effectively scale your Celery-based application to handle increased loads and ensure reliable task execution in a production environment.&lt;/p&gt;




</description>
      <category>celery</category>
      <category>python</category>
      <category>fastapi</category>
      <category>taskmanager</category>
    </item>
    <item>
      <title>MongoDB Shell Commands - A Comprehensive Guide</title>
      <dc:creator>Dhananjay Haridas</dc:creator>
      <pubDate>Sat, 13 Apr 2024 22:04:49 +0000</pubDate>
      <link>https://dev.to/dhananjayharidas/mongodb-shell-commands-a-comprehensive-guide-35cl</link>
      <guid>https://dev.to/dhananjayharidas/mongodb-shell-commands-a-comprehensive-guide-35cl</guid>
      <description>&lt;h3&gt;
  
  
  Step 1: Start MongoDB Shell
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open your terminal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the &lt;code&gt;mongo&lt;/code&gt; command to start the MongoDB shell:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mongo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Switch to a Database
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;To switch to a specific database, use the &lt;code&gt;use&lt;/code&gt; command followed by the name of the database:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;use mydatabase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;mydatabase&lt;/code&gt; with the name of your database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Show Databases
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;To show all databases available on the MongoDB server, run the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;show databases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will list all databases, including empty databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Show Collections
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;After switching to a database, you can list all collections within that database using the &lt;code&gt;show collections&lt;/code&gt; command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;show collections
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will display all collections present in the current database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Show Data from a Collection
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;To display all documents (data) in a collection, use the &lt;code&gt;db.collectionName.find()&lt;/code&gt; method. Replace &lt;code&gt;collectionName&lt;/code&gt; with the name of your collection:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.collectionName.find&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, to display all documents in a collection named &lt;code&gt;users&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;db.users.find&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;You can also apply query criteria to filter the results. For example, to find documents where the &lt;code&gt;age&lt;/code&gt; field is greater than 18:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.collectionName.find&lt;span class="o"&gt;({&lt;/span&gt; age: &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$gt&lt;/span&gt;: 18 &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Insert Documents into a Collection
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;To insert documents into a collection, use the &lt;code&gt;db.collectionName.insertOne()&lt;/code&gt; or &lt;code&gt;db.collectionName.insertMany()&lt;/code&gt; methods.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, to insert a single document into a collection named &lt;code&gt;users&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;db.users.insertOne&lt;span class="o"&gt;({&lt;/span&gt; name: &lt;span class="s2"&gt;"John"&lt;/span&gt;, age: 30 &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;To insert multiple documents into a collection:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.users.insertMany&lt;span class="o"&gt;([&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt; name: &lt;span class="s2"&gt;"Alice"&lt;/span&gt;, age: 25 &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt; name: &lt;span class="s2"&gt;"Bob"&lt;/span&gt;, age: 35 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7: Update Documents in a Collection
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;To update documents in a collection, use the &lt;code&gt;db.collectionName.updateOne()&lt;/code&gt; or &lt;code&gt;db.collectionName.updateMany()&lt;/code&gt; methods.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, to update a single document in the &lt;code&gt;users&lt;/code&gt; collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.users.updateOne&lt;span class="o"&gt;({&lt;/span&gt; name: &lt;span class="s2"&gt;"John"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$set&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; age: 31 &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;To update multiple documents:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.users.updateMany&lt;span class="o"&gt;({&lt;/span&gt; age: &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$lt&lt;/span&gt;: 30 &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$set&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; category: &lt;span class="s2"&gt;"Young"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 8: Delete Documents from a Collection
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;To delete documents from a collection, use the &lt;code&gt;db.collectionName.deleteOne()&lt;/code&gt; or &lt;code&gt;db.collectionName.deleteMany()&lt;/code&gt; methods.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, to delete a single document from the &lt;code&gt;users&lt;/code&gt; collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.users.deleteOne&lt;span class="o"&gt;({&lt;/span&gt; name: &lt;span class="s2"&gt;"John"&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;To delete multiple documents:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.users.deleteMany&lt;span class="o"&gt;({&lt;/span&gt; category: &lt;span class="s2"&gt;"Young"&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 9: Exit MongoDB Shell
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;To exit the MongoDB shell, type &lt;code&gt;exit&lt;/code&gt; and press Enter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands cover the basic CRUD operations (Create, Read, Update, Delete) in MongoDB from the shell. Adjust the database, collection names, and query criteria as needed for your specific use case.&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>database</category>
    </item>
    <item>
      <title>MongoDB Installation Guide for Windows Subsystem for Linux (WSL)</title>
      <dc:creator>Dhananjay Haridas</dc:creator>
      <pubDate>Sat, 13 Apr 2024 21:55:17 +0000</pubDate>
      <link>https://dev.to/dhananjayharidas/mongodb-installation-guide-for-windows-subsystem-for-linux-wsl-21kj</link>
      <guid>https://dev.to/dhananjayharidas/mongodb-installation-guide-for-windows-subsystem-for-linux-wsl-21kj</guid>
      <description>&lt;p&gt;This guide will assist you in installing MongoDB using the Windows Subsystem for Linux (WSL) via the Command Line.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install MongoDB - Community Edition
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Launch a terminal (the Ubuntu app) and navigate to the root of the Ubuntu File System by typing &lt;code&gt;cd ~&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Copy and paste the following command into the terminal to import the MongoDB public GPG Key:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Next, add the MongoDB package to your sources list by pasting this line into the terminal:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: Ensure you are on Ubuntu Xenial. We'll update this for Zesty LTS when available.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Refresh your local package database with the command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   sudo apt-get update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install MongoDB by running the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   sudo apt-get install -y mongodb-org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install the latest stable version (MongoDB 3.6 at the time of writing). Refer to the provided link if you wish to install a different version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolve Unmet Dependencies Error
&lt;/h3&gt;

&lt;p&gt;If you encounter an error regarding unmet dependencies, execute the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download &lt;code&gt;libssl1.1_1.1.1f-1ubuntu2_amd64.deb&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install the downloaded package using &lt;code&gt;dpkg&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Data and DB Directories
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Ensure you are still in the root of the Ubuntu FS by typing &lt;code&gt;cd ~&lt;/code&gt;. Confirm with &lt;code&gt;pwd&lt;/code&gt;, which should display &lt;code&gt;/home/&amp;lt;user&amp;gt;/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create the necessary directories by typing:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   sudo mkdir -p data/db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates a &lt;code&gt;data&lt;/code&gt; directory with a &lt;code&gt;db&lt;/code&gt; subdirectory. The &lt;code&gt;-p&lt;/code&gt; flag ensures the parent directory is created if it doesn't exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start mongod Server and mongo Shell
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open a new terminal window and run the following command to start the MongoDB server:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   sudo mongod --dbpath ~/data/db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see status messages, with the last line indicating that the server is waiting for connections on port 27017.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In another WSL window, type &lt;code&gt;mongo&lt;/code&gt; to launch the MongoDB shell.&lt;br&gt;
You'll see a connection notification in the first terminal window and the prompt in the new window should change to &lt;code&gt;&amp;gt;&lt;/code&gt; indicating you're in the mongo shell.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refer to &lt;a href="https://github.com/michaeltreat/Mongo_quickstart" rel="noopener noreferrer"&gt;this cheat sheet&lt;/a&gt; for guidance on using the mongo shell.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To exit the shell, press &lt;code&gt;Ctrl + C&lt;/code&gt;. You'll receive a confirmation message before returning to the command line.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Troubleshooting
&lt;/h3&gt;

&lt;p&gt;For further assistance, consult the &lt;a href="https://docs.mongodb.com/manual/installation/" rel="noopener noreferrer"&gt;MongoDB Install Docs&lt;/a&gt; or feel free to reach out directly via message or email.&lt;/p&gt;

&lt;p&gt;credis - &lt;br&gt;
&lt;a href="https://github.com/michaeltreat/Windows-Subsystem-For-Linux-Setup-Guide/blob/master/readmes/installs/MongoDB.md?plain=1" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/50375979/getting-error-while-installing-mongodb-in-linux" rel="noopener noreferrer"&gt;stackoverflow&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>wsl</category>
      <category>ubuntu</category>
      <category>linux</category>
    </item>
    <item>
      <title>Windows Subsystem for Linux (WSL) Installation and Configuration Guide</title>
      <dc:creator>Dhananjay Haridas</dc:creator>
      <pubDate>Sat, 06 Apr 2024 08:37:39 +0000</pubDate>
      <link>https://dev.to/dhananjayharidas/windows-subsystem-for-linux-wsl-installation-and-configuration-guide-4dp4</link>
      <guid>https://dev.to/dhananjayharidas/windows-subsystem-for-linux-wsl-installation-and-configuration-guide-4dp4</guid>
      <description>&lt;p&gt;This comprehensive guide offers detailed instructions on setting up and configuring Ubuntu within the Windows Subsystem for Linux (WSL). WSL is a compatibility layer provided by Microsoft that enables users to run native Linux command-line tools directly on Windows 10 and Windows 11. By integrating a Linux kernel interface, WSL bridges the gap between the Windows and Linux ecosystems, providing users with the flexibility to leverage the strengths of both operating systems without the need for dual-booting or virtual machines.&lt;/p&gt;

&lt;p&gt;Why Use WSL?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Seamless Integration: With WSL, users can seamlessly integrate Linux tools and utilities into their Windows workflow, enhancing productivity and development capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compatibility: WSL ensures compatibility with a wide range of Linux software, allowing users to run popular applications, programming languages, and development environments natively on Windows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resource Efficiency: Unlike traditional virtual machines, WSL offers lightweight resource utilization, minimizing overhead and maximizing system performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Development Environment: WSL provides developers with a familiar Linux environment for software development, enabling them to utilize command-line tools, package managers, and development frameworks seamlessly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installing WSL (Windows Subsystem for Linux)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open PowerShell as Administrator&lt;/strong&gt;: Right-click the Start menu, then select "Windows PowerShell (Admin)".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install WSL&lt;/strong&gt;: Run the following command in PowerShell:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   wsl &lt;span class="nt"&gt;--install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will enable the WSL feature on your system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Switching to WSL 2
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set Default WSL Version to 2&lt;/strong&gt;: After installing WSL, switch to WSL 2 by running:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   wsl &lt;span class="nt"&gt;--set-default-version&lt;/span&gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that any new Linux distributions installed will use WSL 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Linux Distributions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;List Available Linux Distributions&lt;/strong&gt;: To see all available Linux distributions in the Microsoft Store, use:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   wsl &lt;span class="nt"&gt;--list&lt;/span&gt; &lt;span class="nt"&gt;--online&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will display a list of Linux distributions that you can install.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install Ubuntu&lt;/strong&gt;: If you choose Ubuntu, you can install it directly using:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   wsl &lt;span class="nt"&gt;--install&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; Ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will download and set up Ubuntu on your system.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check Installed Distributions&lt;/strong&gt;: To see which Linux distributions are installed and their versions, run:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   wsl &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will list all installed distributions along with their respective versions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Ubuntu
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set Default Distribution&lt;/strong&gt;: If Ubuntu is not your default distribution, you can set it using:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   wsl &lt;span class="nt"&gt;--setdefault&lt;/span&gt; Ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make Ubuntu the default distribution to launch when using WSL.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Configure Ubuntu&lt;/strong&gt;: After setting Ubuntu as default, update its package lists by running:
&lt;/li&gt;
&lt;/ol&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that you have the latest package information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vb"&gt;&lt;code&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;Markdown&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="n"&gt;provides&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="n"&gt;guide&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;installing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;managing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;configuring&lt;/span&gt; &lt;span class="n"&gt;WSL&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Ubuntu&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;Windows&lt;/span&gt; &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>wsl</category>
      <category>ubuntu</category>
      <category>windows</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
