<?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: Stepan Nikonov</title>
    <description>The latest articles on DEV Community by Stepan Nikonov (@floxolab).</description>
    <link>https://dev.to/floxolab</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3997568%2Fdc0559e7-3a3a-4f2c-9dfe-01c4402a72ff.jpg</url>
      <title>DEV Community: Stepan Nikonov</title>
      <link>https://dev.to/floxolab</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/floxolab"/>
    <language>en</language>
    <item>
      <title>RAG for Small Businesses: AI That Searches Your Company Knowledge</title>
      <dc:creator>Stepan Nikonov</dc:creator>
      <pubDate>Thu, 30 Jul 2026 23:02:43 +0000</pubDate>
      <link>https://dev.to/floxolab/rag-for-small-businesses-ai-that-searches-your-company-knowledge-137n</link>
      <guid>https://dev.to/floxolab/rag-for-small-businesses-ai-that-searches-your-company-knowledge-137n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;RAG sounds technical, but the useful idea is simple: let AI search selected company documents before it answers, instead of asking it to guess from a blank chat window.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most small businesses do not have a knowledge problem because they lack information. They have one because the information is scattered. A price note is in one folder, a refund rule inside an old PDF, a support answer buried in email, a delivery process in someone's private notes. The owner, manager, or senior admin becomes the living search engine.&lt;/p&gt;

&lt;p&gt;This is where RAG can be useful. Not as a black box &lt;a href="https://floxolab.com/blog/ai-agents-for-business" rel="noopener noreferrer"&gt;AI agent&lt;/a&gt;. Not as a replacement for good operations. Just as a practical way to help a team search its own knowledge before asking AI to write an answer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;RAG is not the AI knowing everything.&lt;/strong&gt; It is the AI looking at selected company information first, then answering from that context.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The actual business problem
&lt;/h2&gt;

&lt;p&gt;A small team usually knows the answers. The slow part is finding the right answer at the right moment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new employee asks the same onboarding questions every week.&lt;/li&gt;
&lt;li&gt;Sales needs the latest package details before replying to a lead.&lt;/li&gt;
&lt;li&gt;Support has to search old conversations for a policy answer.&lt;/li&gt;
&lt;li&gt;Operations keeps a checklist in one place and exceptions somewhere else.&lt;/li&gt;
&lt;li&gt;The owner becomes the person everyone asks before making a small decision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A normal keyword search helps only when the person knows the exact word to search for. Real questions are messier. Someone asks "can we still refund this?" while the document says "cancellation window." Someone asks "what do we include in the starter package?" while the pricing file says "basic implementation scope."&lt;/p&gt;

&lt;h2&gt;
  
  
  RAG in plain English
&lt;/h2&gt;

&lt;p&gt;RAG means retrieval-augmented generation. In plain English: the system retrieves relevant information first, gives that information to the AI model, and then asks the model to generate an answer from that context.&lt;/p&gt;

&lt;p&gt;That matters because a normal chatbot can write confidently without knowing your internal rules. A RAG assistant can be told to answer only from selected business documents and to say when the answer is not in the provided knowledge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsb2k73vacb77xlz2t80j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsb2k73vacb77xlz2t80j.png" alt="Simple workflow diagram showing company documents searched by a knowledge assistant before answering a team chat question" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A simple RAG pattern: selected company documents become searchable knowledge, a team asks a question in chat, and the answer is grounded in retrieved context.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What a vector database does
&lt;/h2&gt;

&lt;p&gt;A vector database helps search by meaning, not only by exact keywords. If someone asks about "refund rules" and the document says "cancellation and return policy," a semantic search can still find the right section. That is the useful part; the business does not need a lecture on embeddings before it can benefit from better internal search.&lt;/p&gt;

&lt;p&gt;One practical detail matters: the embedding step is separate from the answer-writing step. An embedding model turns each approved document chunk into a vector. Qdrant stores and searches those vectors. A language model can then write an answer from the retrieved context. Those jobs should not be blurred together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the tools fit
&lt;/h2&gt;

&lt;p&gt;In a small RAG workflow, each tool should have one clear job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;n8n coordinates the workflow.&lt;/strong&gt; It receives a question, triggers the search step, sends the retrieved context to the model, logs the result, and returns the answer to the team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qdrant stores searchable document chunks.&lt;/strong&gt; It keeps selected company knowledge in a form that can be searched by meaning rather than exact wording.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An embedding model creates the vectors.&lt;/strong&gt; This can be OpenAI’s embedding API or another dedicated embedding model. Its job is to convert the documents and the user’s question into comparable numerical representations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A language model writes the answer.&lt;/strong&gt; Groq or another LLM can be used here, but it should answer from the retrieved context rather than invent a policy that is not in the documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Slack gives the team a familiar interface.&lt;/strong&gt; Questions and answers can stay inside a private internal channel instead of another dashboard nobody opens.&lt;/p&gt;

&lt;p&gt;The stack itself is not the point. Qdrant, n8n, an embedding model, an answer model, and Slack are useful only when the workflow answers a real operational question faster and more consistently than manual search.&lt;/p&gt;

&lt;h2&gt;
  
  
  Business questions this can help with
&lt;/h2&gt;

&lt;p&gt;A knowledge assistant is most useful when the answer already exists somewhere, but the team wastes time finding it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pain&lt;/th&gt;
&lt;th&gt;Useful first version&lt;/th&gt;
&lt;th&gt;Human check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;New staff asks the same setup questions.&lt;/td&gt;
&lt;td&gt;Search onboarding docs and SOPs from Slack.&lt;/td&gt;
&lt;td&gt;Escalate missing or outdated answers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sales needs package and pricing details quickly.&lt;/td&gt;
&lt;td&gt;Retrieve the latest service scope, inclusions, and limits.&lt;/td&gt;
&lt;td&gt;Manager approves unusual discounts or exceptions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Support repeats answers from old tickets.&lt;/td&gt;
&lt;td&gt;Search FAQ, policy, and troubleshooting notes.&lt;/td&gt;
&lt;td&gt;Agent reviews before sending to a customer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operations has checklists across files.&lt;/td&gt;
&lt;td&gt;Find the relevant process step or exception rule.&lt;/td&gt;
&lt;td&gt;Owner confirms edge cases.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is why RAG can be a good fit for small team automation work. Many teams already run on Drive folders, PDFs, spreadsheets, Notion pages, email threads, and chat, and the first win is often not replacing those tools. It is making the right parts searchable.&lt;/p&gt;

&lt;p&gt;For &lt;a href="https://floxolab.com/automation-and-optimization-philippines" rel="noopener noreferrer"&gt;small businesses in the Philippines&lt;/a&gt;, the knowledge layer is often less polished than a formal company wiki. It may be a mix of Google Drive folders, Facebook Messenger threads, WhatsApp or Viber chats, Gmail, shared spreadsheets, and a few documents only one person knows about. A useful AI knowledge assistant should respect that reality: start with the approved files and processes, then connect to the team's actual tools only when the workflow is clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this will not fix
&lt;/h2&gt;

&lt;p&gt;RAG does not make bad documents good. If the source material is outdated, contradictory, or missing, the assistant should not pretend otherwise.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It will not decide company policy for you.&lt;/li&gt;
&lt;li&gt;It will not clean years of messy files by itself.&lt;/li&gt;
&lt;li&gt;It should not answer sensitive questions without access control.&lt;/li&gt;
&lt;li&gt;It should not hide uncertainty behind a confident paragraph.&lt;/li&gt;
&lt;li&gt;It still needs testing with real questions from the team.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good version should be allowed to say: "I cannot find that in the provided documents." That answer is sometimes more valuable than a polished guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start smaller than you think
&lt;/h2&gt;

&lt;p&gt;The first version does not need every file the company has ever created.&lt;/p&gt;

&lt;p&gt;A better starting set might be 10 to 30 useful documents: current pricing, service scope, refund policy, onboarding SOP, support FAQ, delivery checklist, and a few internal notes that people already ask about. That is enough to test whether the assistant retrieves useful context before you spend time connecting more systems.&lt;/p&gt;

&lt;p&gt;The first build should also have a narrow promise: answer internal team questions from selected documents. Not update customer records, not send client replies, not make decisions without review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions to map before building
&lt;/h2&gt;

&lt;p&gt;Before turning this into a workflow, map the knowledge first.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which documents are actually current?&lt;/li&gt;
&lt;li&gt;Which questions does the team ask repeatedly?&lt;/li&gt;
&lt;li&gt;Which answers are safe for internal use only?&lt;/li&gt;
&lt;li&gt;Which answers should require manager approval?&lt;/li&gt;
&lt;li&gt;Where should the assistant answer: Slack, email, Notion, or another tool?&lt;/li&gt;
&lt;li&gt;What should happen when the answer is missing or uncertain?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions matter more than the model choice. A fast model connected to messy, unreviewed knowledge will still produce messy answers faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;RAG is useful when the business already has answers, but the team loses time finding them. Start with a small, approved knowledge set, test real questions, and make the assistant show uncertainty instead of filling gaps with confident guesses.&lt;/p&gt;

&lt;p&gt;The practical goal is not to make a chatbot sound impressive. It is to help a team find the right internal answer faster, with enough context for a human to trust, check, or improve it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Want to see the workflow version?&lt;/strong&gt; I built an inspectable &lt;a href="https://floxolab.com/cases/slack-knowledge-bot-n8n" rel="noopener noreferrer"&gt;Slack Knowledge Bot with n8n, Qdrant, and Groq&lt;/a&gt; that answers from approved Google Drive docs, shows sources, and marks low-confidence matches.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.n8n.io/advanced-ai/rag-in-n8n/" rel="noopener noreferrer"&gt;n8n RAG documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreqdrant/" rel="noopener noreferrer"&gt;n8n Qdrant Vector Store node documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qdrant.tech/documentation/overview/" rel="noopener noreferrer"&gt;Qdrant documentation overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/guides/embeddings" rel="noopener noreferrer"&gt;OpenAI embeddings documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://console.groq.com/docs/models" rel="noopener noreferrer"&gt;Groq models documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://floxolab.com/blog/rag-knowledge-assistant-business" rel="noopener noreferrer"&gt;FloxoLab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>automation</category>
      <category>llm</category>
    </item>
    <item>
      <title>How to Fix Core Web Vitals: LCP, CLS, and INP in Plain English</title>
      <dc:creator>Stepan Nikonov</dc:creator>
      <pubDate>Sun, 26 Jul 2026 19:33:34 +0000</pubDate>
      <link>https://dev.to/floxolab/how-to-fix-core-web-vitals-lcp-cls-and-inp-in-plain-english-1ob1</link>
      <guid>https://dev.to/floxolab/how-to-fix-core-web-vitals-lcp-cls-and-inp-in-plain-english-1ob1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I took this site from a mobile score of 77 to 98, and to 100 on desktop. Here is what each Core Web Vital measures, what drags it down, and the fixes that actually moved the numbers, in plain language you can act on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Core Web Vitals are three numbers Google uses to measure how a page feels to a real person: how fast the main content loads, whether the layout jumps around while it does, and how quickly the page reacts when you tap or click. They are part of Google's page experience signals, which means they work as a ranking tie-breaker. Between two pages that answer a query equally well, the faster, steadier one has the edge.&lt;/p&gt;

&lt;p&gt;This guide explains each of the three, plus the supporting numbers you will see in the same report, and then shows the real fixes that took this site's mobile score from 77 to 98. Nothing here is theory. It is the same work I run on client sites in an &lt;a href="https://floxolab.com/seo-audit" rel="noopener noreferrer"&gt;SEO audit&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a good result looks like
&lt;/h2&gt;

&lt;p&gt;Here is where this site sits today, straight from Google's PageSpeed Insights: 98 on mobile and 100 on desktop, on the same code. The two tests look different because mobile is run on a throttled, slower simulated device, so it always has less room to work with. Mobile is the harder target, and since mobile traffic dominates most sites, its real-user data usually carries the most ranking weight, so it is the score worth chasing. Google measures mobile and desktop separately, so desktop still counts too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmk97r5ue0js78zvlb3qh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmk97r5ue0js78zvlb3qh.webp" alt="PageSpeed Insights mobile report for this site: performance 98, LCP 1.9 seconds, CLS 0, total blocking time 40 milliseconds, all green" width="800" height="727"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Mobile: performance 98, LCP 1.9s, CLS 0, all vitals in the green.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdqztmqut6gc4zv2aych.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdqztmqut6gc4zv2aych.webp" alt="PageSpeed Insights desktop report for this site: performance 100, LCP 0.5 seconds, CLS 0, and speed index 0.4 seconds" width="800" height="725"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Desktop: performance 100, LCP 0.5s, CLS 0, speed index 0.4s.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The three Core Web Vitals, one at a time
&lt;/h2&gt;

&lt;p&gt;Everything on the scoreboard comes down to three real-user metrics. A page passes when 75 percent of real visitors fall inside the "good" band for each.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Measures&lt;/th&gt;
&lt;th&gt;Good&lt;/th&gt;
&lt;th&gt;Poor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LCP (Largest Contentful Paint)&lt;/td&gt;
&lt;td&gt;Loading&lt;/td&gt;
&lt;td&gt;2.5s or less&lt;/td&gt;
&lt;td&gt;Over 4s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLS (Cumulative Layout Shift)&lt;/td&gt;
&lt;td&gt;Visual stability&lt;/td&gt;
&lt;td&gt;0.1 or less&lt;/td&gt;
&lt;td&gt;Over 0.25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INP (Interaction to Next Paint)&lt;/td&gt;
&lt;td&gt;Responsiveness&lt;/td&gt;
&lt;td&gt;200ms or less&lt;/td&gt;
&lt;td&gt;Over 500ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  LCP: how fast the main thing loads
&lt;/h3&gt;

&lt;p&gt;Largest Contentful Paint is the moment the biggest element in view finishes rendering, usually the hero image or the headline block. It is the reader's gut sense of "has this page loaded yet". What drags it down is nearly always one of four things: a heavy, uncompressed hero image, a slow server or host, render-blocking CSS and JavaScript that must run before anything paints, and web fonts that arrive late.&lt;/p&gt;

&lt;p&gt;The fixes follow the causes. Compress and serve the hero as WebP at the right size, and preload it so the browser fetches it early. Use srcset so a phone pulls a small version and a desktop a larger one, instead of shipping one heavy file to every device. That is a separate lever from preloading: preload fetches the image sooner, srcset makes sure it is the right weight, and on a slow mobile connection the srcset part is often what saves the most. Cut or defer render-blocking scripts, and self-host your fonts instead of pulling them from a third-party domain. On this site LCP is 1.9s on mobile and 0.5s on desktop, and the single biggest lever was the hero image: right format, right size per device, preloaded.&lt;/p&gt;

&lt;h3&gt;
  
  
  CLS: whether the page holds still
&lt;/h3&gt;

&lt;p&gt;Cumulative Layout Shift measures how much the content jumps around as the page loads. You have felt it: you go to tap a link, an image or banner loads above it, and the whole page shoves down. The usual culprits are images and embeds with no width and height set, ad or banner slots injected after load, and fonts that swap and reflow the text.&lt;/p&gt;

&lt;p&gt;This is the most fixable vital, and the cheapest win on the list. Put explicit width and height (or an aspect ratio) on every image and iframe so the browser reserves the space before the file arrives. Give injected elements a fixed slot. Set font-display so a font swap does not reshuffle the layout. This site sits at a CLS of 0, and it got there almost entirely by adding size attributes to images.&lt;/p&gt;

&lt;h3&gt;
  
  
  INP: how fast the page answers you
&lt;/h3&gt;

&lt;p&gt;Interaction to Next Paint replaced First Input Delay in March 2024. It measures the delay between you doing something, a tap, a click, a keypress, and the page actually showing a response, taking close to the worst interaction across the whole visit. A high INP is a page that feels sluggish and unresponsive, and the cause is almost always JavaScript hogging the main thread: heavy frameworks, big third-party scripts, and long tasks that block the browser from reacting. It is also the vital the most sites fail, so it is worth the attention.&lt;/p&gt;

&lt;p&gt;The fix is to give the main thread less to do. Defer or split heavy JavaScript, hold third-party scripts off the critical path until the user needs them, and break long tasks into smaller pieces. The clearest example on this site is analytics: the Google tag does not load until the first interaction or the browser goes idle, so it never blocks that first tap. That one change keeps total blocking time, the lab stand-in for INP, at 40 milliseconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The other numbers in the report
&lt;/h2&gt;

&lt;p&gt;The same Lighthouse report shows three more metrics. These are lab diagnostics, useful for finding problems, but they are not the vitals Google ranks on.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First Contentful Paint (FCP).&lt;/strong&gt; When the first text or image appears. An early signal that something is happening.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Total Blocking Time (TBT).&lt;/strong&gt; How long the main thread was blocked during load. It is the lab proxy for INP, so lowering TBT usually lowers INP for real users too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed Index.&lt;/strong&gt; How quickly the page visibly fills in. On this site it shows 3.5s on mobile and lands in the amber band, while every actual vital is green. That is a fair reminder that the overall score is a blend, and a single amber lab number is not worth panicking over when the real-user vitals all pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lab data and field data are not the same
&lt;/h2&gt;

&lt;p&gt;There are two ways to measure all of this, and mixing them up causes a lot of confusion. &lt;strong&gt;Lab data&lt;/strong&gt; is a single simulated test, like the Lighthouse run in the screenshots above, on a fixed device and connection. It is repeatable and great for debugging. &lt;strong&gt;Field data&lt;/strong&gt; is what real Chrome users actually experienced over the last 28 days, and it is what Google uses for ranking. You can see your own field data in the Core Web Vitals report inside Search Console.&lt;/p&gt;

&lt;p&gt;The practical order: use the lab test to find and fix problems fast, then watch the field data in Search Console to confirm real users feel the change. A lab score can be perfect while the field still lags, especially on a page that only just got fixed, because the field window is a rolling average. Reading that report is part of the wider habit covered in &lt;a href="https://floxolab.com/seo/guides/how-to-read-your-monthly-seo-report" rel="noopener noreferrer"&gt;how to read your monthly SEO report&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually moved this site from 77 to 98
&lt;/h2&gt;

&lt;p&gt;The jump was not one clever trick. It was a short list of unglamorous fixes, each aimed at a specific metric:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Self-hosted the fonts.&lt;/strong&gt; Pulling fonts from a third-party domain adds a connection and a render delay. Serving them from the same domain, preloaded, cut straight into LCP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deferred analytics off the critical path.&lt;/strong&gt; The Google tag now loads on first interaction or idle instead of during load, which kept total blocking time, and therefore INP, low.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsive images in WebP.&lt;/strong&gt; Every image ships as WebP at several sizes with srcset, so a phone downloads a small file and a desktop a larger one, never the wrong one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Width and height on everything.&lt;/strong&gt; Explicit dimensions on images and figures reserve their space, which is why CLS is 0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that touched the design or the content. It is exactly the kind of finite, technical work that a small site needs once, not every month, which is the point I make in &lt;a href="https://floxolab.com/seo/guides/technical-seo-fixes-agencies-wont-touch" rel="noopener noreferrer"&gt;the technical SEO fixes agencies won't touch&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Compress the hero image, serve it as WebP, and preload it.&lt;/li&gt;
&lt;li&gt;Set width and height on every image, iframe, and embed.&lt;/li&gt;
&lt;li&gt;Self-host fonts and set font-display so text does not reflow.&lt;/li&gt;
&lt;li&gt;Defer analytics and other third-party scripts off the load path.&lt;/li&gt;
&lt;li&gt;Test in the lab with PageSpeed Insights, then confirm in Search Console field data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What are Core Web Vitals?
&lt;/h3&gt;

&lt;p&gt;Three metrics Google uses to measure real-world page experience: Largest Contentful Paint (LCP) for loading, Cumulative Layout Shift (CLS) for visual stability, and Interaction to Next Paint (INP) for responsiveness. They come from real Chrome users and feed into ranking as a page experience signal.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a good Core Web Vitals score?
&lt;/h3&gt;

&lt;p&gt;A page passes when 75 percent of real users see LCP at 2.5s or less, CLS at 0.1 or less, and INP at 200ms or less. In the Lighthouse lab test the overall score is good from 90 to 100. This site scores 98 on mobile and 100 on desktop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is my mobile score lower than desktop?
&lt;/h3&gt;

&lt;p&gt;Lighthouse tests mobile on a throttled, slower simulated device and connection, so the same page has less CPU and bandwidth to work with. Mobile is the harder target, and because mobile traffic dominates most sites, its real-user data usually carries the most ranking weight, so it is the score to optimise for. Google measures mobile and desktop separately, so desktop still counts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do Core Web Vitals affect SEO rankings?
&lt;/h3&gt;

&lt;p&gt;Yes, as a tie-breaker rather than a magic lever. Between two pages of similar relevance, the faster and steadier one has an edge. Fixing vitals will not outrank a far more relevant page on its own, but poor vitals can hold back a page that otherwise deserves to rank.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.dev/articles/vitals" rel="noopener noreferrer"&gt;web.dev: Web Vitals and the Core Web Vitals thresholds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/search/docs/appearance/page-experience" rel="noopener noreferrer"&gt;Google Search Central: page experience and Core Web Vitals in ranking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pagespeed.web.dev/" rel="noopener noreferrer"&gt;PageSpeed Insights: the lab and field report used above&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://floxolab.com/seo/guides/how-to-fix-core-web-vitals" rel="noopener noreferrer"&gt;FloxoLab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webperf</category>
      <category>webdev</category>
      <category>seo</category>
      <category>performance</category>
    </item>
    <item>
      <title>Slack Knowledge Bot with n8n, Qdrant, and Groq</title>
      <dc:creator>Stepan Nikonov</dc:creator>
      <pubDate>Fri, 24 Jul 2026 10:49:36 +0000</pubDate>
      <link>https://dev.to/floxolab/slack-knowledge-bot-with-n8n-qdrant-and-groq-253p</link>
      <guid>https://dev.to/floxolab/slack-knowledge-bot-with-n8n-qdrant-and-groq-253p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A practical workflow that turns approved Google Drive docs into a Slack assistant. It chunks selected files, stores embeddings in Qdrant, retrieves relevant context, asks Groq to answer only from that context, and replies with sources or a low-confidence note.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many teams already have the answer somewhere: a pricing note, an onboarding doc, a service FAQ, a checklist, or a handoff process. The slow part is finding the right section while work is happening.&lt;/p&gt;

&lt;p&gt;This workflow gives Slack a searchable knowledge layer. A team member asks a question, n8n searches an approved Google Drive folder through Qdrant, and Groq writes an answer from the retrieved context with source files attached.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The useful part is not a confident answer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is a traceable answer: what documents were searched, which sources were used, and whether the match was weak enough to treat with caution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Knowledge source&lt;/th&gt;
&lt;th&gt;Search layer&lt;/th&gt;
&lt;th&gt;Team interface&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Approved Google Drive Markdown files&lt;/td&gt;
&lt;td&gt;Qdrant vectors from local embeddings&lt;/td&gt;
&lt;td&gt;Slack mention with sources&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Approximate running cost
&lt;/h2&gt;

&lt;p&gt;For this demo, the software bill can stay very low. Ollama runs the embedding model locally. n8n can run as a free self-hosted community edition. Qdrant can run locally or start on a free cloud tier for testing. Groq is the main paid API part, and a small internal bot like this can often be tested on a small balance when question volume is modest.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ollama embeddings:&lt;/strong&gt; no API bill when the embedding model runs on your own machine or server. The cost is local compute.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;n8n:&lt;/strong&gt; free if self-hosted, with hosting and maintenance still owned by someone. n8n Cloud is paid if you want managed hosting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Qdrant:&lt;/strong&gt; local/self-hosted can be free to run as software. Qdrant Cloud also has a free tier for testing and prototypes, with paid usage when the project grows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Groq:&lt;/strong&gt; the answer generation step is usage-based. For a low-volume demo, a small balance such as USD 5 can be enough to test the pattern for a while, but real spend depends on model choice, prompt size, and usage volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Low software cost to start. Real cost is hosting, API calls, and whoever maintains it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Groq:&lt;/strong&gt; the answer generation step is usage-based. For a low-volume demo, a small balance such as USD 5 can be enough to test the pattern for a while, but real spend depends on model choice, prompt size, and usage volume.&lt;/p&gt;

&lt;p&gt;Low software cost to start. Real cost is hosting, API calls, and whoever maintains it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The full workflow map
&lt;/h2&gt;

&lt;p&gt;The canvas has two lanes. The top lane refreshes the knowledge base: list files, filter approved text files, chunk them, embed them, delete old chunks for the same source, and upsert the fresh points into Qdrant. The bottom lane answers questions from Slack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frgypqzbw8itw010qh32q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frgypqzbw8itw010qh32q.png" alt="n8n workflow canvas for a Slack knowledge bot with Google Drive ingestion and Slack answer paths" width="800" height="368"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Two visible paths: document ingestion on top, Slack question answering below.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Start with approved docs
&lt;/h2&gt;

&lt;p&gt;The workflow starts from a controlled Google Drive folder. In this demo, the folder contains Markdown files for FloxoLab pricing, services, FAQ, workflow examples, onboarding, and intake process notes.&lt;/p&gt;

&lt;p&gt;That matters because a useful knowledge bot should not begin by crawling a messy shared drive. The first version should use current, approved documents that are safe for internal answers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F802xiv2ro9lm1jidp4k7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F802xiv2ro9lm1jidp4k7.png" alt="Google Drive demo folder containing selected Markdown knowledge files" width="799" height="322"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The workflow filters for Markdown files, so the first knowledge base stays simple and reviewable.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Chunk the files with metadata
&lt;/h2&gt;

&lt;p&gt;Each file is downloaded and passed through a code node that splits text by headings, keeps chunks under a practical word limit, and adds metadata such as source, file index, chunk index, word count, and last modified time.&lt;/p&gt;

&lt;p&gt;Metadata is not decoration. It is what lets the answer show where the context came from, and it gives the workflow a clean way to replace old chunks from the same source during the next ingestion run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff41je3arqox47vf9zu5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff41je3arqox47vf9zu5b.png" alt="n8n Smart Chunk and Metadata output showing chunk text source chunk index and word count" width="800" height="866"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Each chunk carries source and index data, not just text.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Store searchable chunks in Qdrant
&lt;/h2&gt;

&lt;p&gt;The workflow uses Ollama with &lt;code&gt;nomic-embed-text&lt;/code&gt; for embeddings, then prepares a Qdrant point with a deterministic id, vector, and payload. Before upserting new points, it deletes old chunks for the same source so stale content does not sit beside fresh content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faruravnt52hov99czkle.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faruravnt52hov99czkle.png" alt="Qdrant collection showing stored knowledge chunks with text source chunk index and vector length" width="800" height="626"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Qdrant stores the vector plus the payload fields the workflow needs later: text, source, chunk index, timestamps, and word count.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Ask from Slack
&lt;/h2&gt;

&lt;p&gt;The question flow starts when someone mentions the bot in Slack. n8n removes the mention text, embeds the clean question, searches Qdrant for the top matching chunks, and builds a compact context block for Groq.&lt;/p&gt;

&lt;p&gt;The answer prompt is deliberately strict: answer only from the provided context, do not invent pricing, services, guarantees, timelines, or policies, and keep the message concise enough for Slack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyb57u4a0ebel784zzd4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyb57u4a0ebel784zzd4f.png" alt="Slack question and bot answer showing sources from approved knowledge files" width="800" height="209"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The user asks inside Slack. The bot answers from the retrieved context and appends source files.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Make uncertainty visible
&lt;/h2&gt;

&lt;p&gt;The workflow also marks weak retrieval. If the top Qdrant score is below the threshold, the answer includes a low-confidence note. That is a practical guardrail because the user can see the answer should be checked before it becomes a decision.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftxawqwdgqf0d9wl0hzck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftxawqwdgqf0d9wl0hzck.png" alt="Slack bot low confidence response when the answer is not found in the approved documents" width="800" height="177"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A missing answer should stay visible. Here the bot says it does not know and marks the match as low confidence.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would improve next
&lt;/h2&gt;

&lt;p&gt;The demo proves the path, but a production version should make ownership clearer.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better source links.&lt;/strong&gt; File names are useful, but links back to the exact Google Drive document would make review faster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Threaded Slack replies.&lt;/strong&gt; Posting answers in the original thread would keep channels cleaner.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Low-confidence review.&lt;/strong&gt; Weak matches could be logged to a sheet or sent to a private review channel.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ingestion logs.&lt;/strong&gt; A clear record of files, chunk counts, and failures would make handoff easier.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;A Slack knowledge bot is useful when the answer already exists, but the team wastes time finding it. The important choices are not only model and database. They are the approved knowledge set, the retrieval threshold, the source display, and the fallback behavior.&lt;/p&gt;

&lt;p&gt;This workflow keeps those parts visible: selected docs in, searchable chunks stored, Slack question asked, context retrieved, answer written from that context, sources shown, uncertainty surfaced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related guide
&lt;/h2&gt;

&lt;p&gt;For the plain-English explanation behind this pattern, read &lt;a href="https://floxolab.com/blog/rag-knowledge-assistant-business" rel="noopener noreferrer"&gt;RAG for Small Businesses: AI That Searches Your Company Knowledge&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://floxolab.com/cases/slack-knowledge-bot-n8n" rel="noopener noreferrer"&gt;FloxoLab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>n8n</category>
      <category>ai</category>
      <category>rag</category>
      <category>automation</category>
    </item>
    <item>
      <title>n8n Webhook Not Working? Test URL, Production URL, and 404 Fixes</title>
      <dc:creator>Stepan Nikonov</dc:creator>
      <pubDate>Tue, 21 Jul 2026 07:25:33 +0000</pubDate>
      <link>https://dev.to/floxolab/n8n-webhook-not-working-test-url-production-url-and-404-fixes-2c17</link>
      <guid>https://dev.to/floxolab/n8n-webhook-not-working-test-url-production-url-and-404-fixes-2c17</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;If an n8n webhook receives nothing or returns 404, check the URL mode and registration state before changing the workflow. This guide follows the shortest useful diagnostic order.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An n8n webhook normally fails before the first workflow node runs. A 404 usually means the request did not match a registered webhook route. The common causes are a test URL with no active listener, a production URL for an unpublished workflow, the wrong HTTP method, a changed path, or an incorrect public URL on a self-hosted instance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Fastest check:&lt;/strong&gt; open the Webhook node, copy the URL again, confirm whether it is Test or Production, and send the same HTTP method configured in the node. Do this before debugging credentials, expressions, or downstream nodes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Start with the symptom
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Most likely check&lt;/th&gt;
&lt;th&gt;First action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Test URL returns 404&lt;/td&gt;
&lt;td&gt;No current test listener&lt;/td&gt;
&lt;td&gt;Select &lt;strong&gt;Listen for test event&lt;/strong&gt;, then resend within 120 seconds.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production URL returns 404&lt;/td&gt;
&lt;td&gt;Workflow is not published&lt;/td&gt;
&lt;td&gt;Publish the workflow and copy the Production URL again.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL works in a browser but not from the app&lt;/td&gt;
&lt;td&gt;GET versus POST mismatch&lt;/td&gt;
&lt;td&gt;Match the sender's method to the Webhook node.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL has the wrong domain, port, or protocol&lt;/td&gt;
&lt;td&gt;Self-hosted proxy configuration&lt;/td&gt;
&lt;td&gt;Check &lt;code&gt;WEBHOOK_URL&lt;/code&gt;, proxy hops, and forwarded headers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Webhook runs but no data appears on the canvas&lt;/td&gt;
&lt;td&gt;Production execution&lt;/td&gt;
&lt;td&gt;Open the workflow's &lt;strong&gt;Executions&lt;/strong&gt; tab.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Test URL versus Production URL
&lt;/h2&gt;

&lt;p&gt;Every Webhook node exposes two URLs at the top of its panel. The &lt;a href="https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/" rel="noopener noreferrer"&gt;official Webhook node documentation&lt;/a&gt; treats them as two different operating modes, not interchangeable copies of the same endpoint.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use the Test URL while building
&lt;/h3&gt;

&lt;p&gt;Select &lt;strong&gt;Test URL&lt;/strong&gt;, then select &lt;strong&gt;Listen for test event&lt;/strong&gt; before the external system sends its request. n8n registers the test webhook for 120 seconds and displays the incoming data in the editor. If the timer expires, register it again and resend the event.&lt;/p&gt;

&lt;p&gt;Opening the workflow is not enough by itself. A saved test URL can return 404 later because test registration is temporary. This is useful during development because it lets one test payload appear directly on the canvas, but it is the wrong URL for a service that must call n8n at any time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use the Production URL after publishing
&lt;/h3&gt;

&lt;p&gt;Select &lt;strong&gt;Production URL&lt;/strong&gt;, copy it into the sending service, and &lt;strong&gt;Publish&lt;/strong&gt; the workflow. Current n8n documentation uses Publish terminology. Publishing registers the production webhook and makes the published workflow version available to external requests until the workflow is unpublished.&lt;/p&gt;

&lt;p&gt;Production payloads do not appear live on the editor canvas. Open &lt;strong&gt;Executions&lt;/strong&gt; to confirm whether the request created a production execution and to inspect its input. No data on the canvas does not mean the webhook failed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The n8n webhook 404 checklist
&lt;/h2&gt;

&lt;p&gt;Run these checks in order. Stop as soon as the request reaches n8n.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Copy the URL from the node again.&lt;/strong&gt; Do not rely on a URL saved in an old note, form, app, or API client.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirm Test or Production.&lt;/strong&gt; Test requires a temporary listener. Production requires a published workflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirm the HTTP method.&lt;/strong&gt; A POST request does not match a webhook registered only for GET.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compare the path exactly.&lt;/strong&gt; Check spelling, hyphens, route parameters, and any path changed after the sender was configured.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check for a path-and-method conflict.&lt;/strong&gt; n8n permits only one registered webhook for each path and method combination.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inspect the public base URL.&lt;/strong&gt; Do this only for self-hosted n8n behind a reverse proxy or when the node displays an internal hostname, HTTP instead of HTTPS, or the wrong port.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Check the HTTP method before the payload
&lt;/h2&gt;

&lt;p&gt;The Webhook node supports GET, POST, PUT, PATCH, DELETE, and HEAD. By default it accepts one method. The sender must use that exact method. Pasting a webhook URL into a browser sends GET, so a successful browser test does not prove that a service's POST request will match, and the reverse is also true.&lt;/p&gt;

&lt;p&gt;Current n8n versions can allow multiple HTTP methods from the node's Settings. Use that only when the endpoint genuinely needs more than one method. A tighter single-method webhook is easier to reason about and reduces accidental calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the webhook path
&lt;/h2&gt;

&lt;p&gt;n8n generates a random path by default, and you can replace it with a stable custom path. Once an external app stores the URL, changing the Path field changes the route it must call. Copy the complete URL after every path change instead of editing only the last segment by hand.&lt;/p&gt;

&lt;p&gt;n8n also requires each registered path and HTTP method combination to be unique. If another published workflow already owns the same combination, unpublish the conflicting workflow or choose a different path or method. The &lt;a href="https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/common-issues/" rel="noopener noreferrer"&gt;Webhook common-issues page&lt;/a&gt; documents both method matching and route conflicts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Send a minimal request
&lt;/h2&gt;

&lt;p&gt;Remove the external app from the diagnosis. Copy the exact URL from the Webhook node and test it with a safe placeholder payload. The example below uses POST. Change the method if your node uses something else.&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="nt"&gt;--request&lt;/span&gt; POST &lt;span class="s1"&gt;'https://n8n.example.com/webhook/example-path'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"event":"webhook-test","id":"demo-001"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the example URL with the full Test or Production URL copied from your node. For a Test URL, select &lt;strong&gt;Listen for test event&lt;/strong&gt; immediately before running the command. For a Production URL, publish first. If this request works, the remaining problem is in the external app's stored URL, method, headers, authentication, or network access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reverse proxy and public URL problems
&lt;/h2&gt;

&lt;p&gt;Skip this section on n8n Cloud. It matters when a self-hosted instance runs internally on one address but a reverse proxy exposes a different public HTTPS address.&lt;/p&gt;

&lt;p&gt;n8n normally builds webhook URLs from &lt;code&gt;N8N_PROTOCOL&lt;/code&gt;, &lt;code&gt;N8N_HOST&lt;/code&gt;, and &lt;code&gt;N8N_PORT&lt;/code&gt;. Behind a proxy, that can produce an internal port or the wrong scheme. The &lt;a href="https://docs.n8n.io/hosting/configuration/configuration-examples/webhook-url/" rel="noopener noreferrer"&gt;official reverse-proxy configuration&lt;/a&gt; says to set the public URL explicitly with &lt;code&gt;WEBHOOK_URL&lt;/code&gt;, set &lt;code&gt;N8N_PROXY_HOPS&lt;/code&gt; to the number of reverse proxies, and pass the forwarded host, protocol, and client information from the last proxy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;WEBHOOK_URL&lt;/span&gt;=&lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;n8n&lt;/span&gt;.&lt;span class="n"&gt;example&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;/
&lt;span class="n"&gt;N8N_PROXY_HOPS&lt;/span&gt;=&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Do not copy this blindly.&lt;/strong&gt; Use your real public HTTPS base URL and the actual number of proxies in the request path. Restart or redeploy n8n after changing environment variables, then copy the regenerated webhook URL from the node.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What to log before handing the webhook into production
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The final Production URL location and which external system owns it. Do not paste secret query parameters into a public document.&lt;/li&gt;
&lt;li&gt;The expected HTTP method, content type, authentication method, and a sanitized example payload.&lt;/li&gt;
&lt;li&gt;The workflow owner and where production executions are reviewed.&lt;/li&gt;
&lt;li&gt;The expected success response and what the sender does when it receives a non-2xx response.&lt;/li&gt;
&lt;li&gt;The alert channel and recovery owner for failures after the webhook starts the workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the route works, broader failures belong in the &lt;a href="https://floxolab.com/blog/n8n-debug-failed-workflows" rel="noopener noreferrer"&gt;n8n workflow debugging guide&lt;/a&gt;. Production ownership and notifications belong in the &lt;a href="https://floxolab.com/blog/n8n-error-workflow-telegram-alerts" rel="noopener noreferrer"&gt;n8n error workflow alerts guide&lt;/a&gt;. Keeping those jobs separate makes the webhook checklist short enough to use during an incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  The production handoff
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Test with the Test URL and one sanitized payload.&lt;/li&gt;
&lt;li&gt;Switch the node to Production URL and copy the full value.&lt;/li&gt;
&lt;li&gt;Publish the workflow.&lt;/li&gt;
&lt;li&gt;Update the external service with the Production URL and matching method.&lt;/li&gt;
&lt;li&gt;Trigger one real but safe event.&lt;/li&gt;
&lt;li&gt;Confirm the run in Executions and record who owns failures.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;n8n autosaves edits, but saved draft changes are not the same as the published version used by production executions. The &lt;a href="https://docs.n8n.io/workflows/publish/" rel="noopener noreferrer"&gt;save and publish documentation&lt;/a&gt; explains that production runs continue to use the current published version until you publish newer changes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://floxolab.com/blog/n8n-webhook-not-working" rel="noopener noreferrer"&gt;FloxoLab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>n8n</category>
      <category>automation</category>
      <category>debugging</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Self-hosting an AI agent is the easy part. The real work is limiting Telegram access and server permissions. I updated this case with a verified Hermes allowlist setup, DeepSeek V4 Pro config, and the sudo risk.</title>
      <dc:creator>Stepan Nikonov</dc:creator>
      <pubDate>Sat, 18 Jul 2026 10:00:51 +0000</pubDate>
      <link>https://dev.to/floxolab/self-hosting-an-ai-agent-is-the-easy-part-the-real-work-is-limiting-telegram-access-and-server-3d9h</link>
      <guid>https://dev.to/floxolab/self-hosting-an-ai-agent-is-the-easy-part-the-real-work-is-limiting-telegram-access-and-server-3d9h</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/floxolab/hermes-agent-self-hosted-ai-assistant-with-persistent-memory-and-telegram-4hih" class="crayons-story__hidden-navigation-link"&gt;Hermes Agent: Self-Hosted AI Assistant with Persistent Memory and Telegram&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/floxolab" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3997568%2Fdc0559e7-3a3a-4f2c-9dfe-01c4402a72ff.jpg" alt="floxolab profile" class="crayons-avatar__image" width="460" height="460"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/floxolab" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Stepan Nikonov
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Stepan Nikonov
                
              
              &lt;div id="story-author-preview-content-4172242" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/floxolab" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3997568%2Fdc0559e7-3a3a-4f2c-9dfe-01c4402a72ff.jpg" class="crayons-avatar__image" alt="" width="460" height="460"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Stepan Nikonov&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/floxolab/hermes-agent-self-hosted-ai-assistant-with-persistent-memory-and-telegram-4hih" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 18&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/floxolab/hermes-agent-self-hosted-ai-assistant-with-persistent-memory-and-telegram-4hih" id="article-link-4172242"&gt;
          Hermes Agent: Self-Hosted AI Assistant with Persistent Memory and Telegram
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/selfhosted"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;selfhosted&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/automation"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;automation&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/floxolab/hermes-agent-self-hosted-ai-assistant-with-persistent-memory-and-telegram-4hih#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            8 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Hermes Agent: Self-Hosted AI Assistant with Persistent Memory and Telegram</title>
      <dc:creator>Stepan Nikonov</dc:creator>
      <pubDate>Sat, 18 Jul 2026 08:21:43 +0000</pubDate>
      <link>https://dev.to/floxolab/hermes-agent-self-hosted-ai-assistant-with-persistent-memory-and-telegram-4hih</link>
      <guid>https://dev.to/floxolab/hermes-agent-self-hosted-ai-assistant-with-persistent-memory-and-telegram-4hih</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A real Hermes Agent setup on a VPS with Telegram allowlisting and persistent memory: installation, security, costs, failures, and daily use.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Claude Projects and ChatGPT Projects are useful, but they have a ceiling. Every session starts fresh unless you manually reload context. Claude Projects with a loaded .md file works, but you maintain that file manually. Hermes maintains its own memory autonomously. For a single question that is fine. For an assistant that handles recurring operational tasks across days and weeks, it means you spend time re-explaining the same things instead of just getting work done.&lt;/p&gt;

&lt;p&gt;The other issue is availability. Managed tools run on someone else's schedule. Rate limits, outages, and interface changes are outside your control. If the assistant is part of your daily operations, that dependency matters.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An assistant that lives on your server remembers what it learns and works on your schedule, not a vendor's.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hermes Agent is open source, MIT licensed, and runs on any VPS from about $5 per month.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setup time&lt;/th&gt;
&lt;th&gt;Monthly cost&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;About 15 minutes from curl to first Telegram message&lt;/td&gt;
&lt;td&gt;$5-7 VPS + $2-5 LLM tokens&lt;/td&gt;
&lt;td&gt;MIT, Nous Research, first released May 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What Hermes actually is
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/nousresearch/hermes-agent" rel="noopener noreferrer"&gt;Hermes Agent&lt;/a&gt; is an open-source autonomous AI agent built by Nous Research. It is not a chatbot wrapper and not a simple Telegram bot. It is a long-running process that lives on your server, remembers what it learns, runs tasks on a schedule, and gets more capable the longer you use it.&lt;/p&gt;

&lt;p&gt;The key difference from Claude Projects or ChatGPT Projects: Hermes maintains its own memory autonomously. After you give it your business context once, it carries that forward across every session. You do not re-explain who you are, what you build, or what your stack looks like every time you open a chat.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Persistent memory:&lt;/strong&gt; Hermes writes structured memories after each session. Next time you start, it already knows your business, your tools, your clients, and your preferences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skills layer:&lt;/strong&gt; After completing a complex task, Hermes writes a reusable skill so it can handle the same task faster next time. The longer it runs, the more capable it becomes at your specific workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduled tasks:&lt;/strong&gt; Cron-based task runner built in. Set a morning digest, a weekly report, or a daily status check. It runs without any trigger from you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools selected at setup:&lt;/strong&gt; Web search, browser automation, file operations, code execution, image generation, and cross-platform messaging can be enabled during setup. Keep the Telegram toolset as small as the actual job allows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bring your own model:&lt;/strong&gt; Hermes supports Anthropic, OpenAI, Google Gemini, DeepSeek, OpenRouter, Nous Portal, local endpoints, and other compatible providers. The model can change without reinstalling the agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local state, external inference:&lt;/strong&gt; Hermes stores its sessions, memory, and skills on your server and does not add its own telemetry. Prompts and relevant tool context still go to the LLM provider you configure unless you use a local model.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Installation runs through a single curl command. The installer auto-detects dependencies, installs Python 3.11 and supporting tools if they are missing, and walks through provider selection, platform configuration, and tool enablement via interactive menus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj5iia9dqzwagmkzvhuk9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj5iia9dqzwagmkzvhuk9.png" alt="Hermes Agent installer terminal output on Ubuntu: auto-detecting Python, Git, Node.js, ripgrep, and ffmpeg dependencies" width="799" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The installer detects Ubuntu, installs missing dependencies automatically, and handles Python version management without manual setup.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fql05aa8f3p3reniznupg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fql05aa8f3p3reniznupg.png" alt="Hermes Agent provider selection menu showing 20-plus LLM providers including Anthropic, OpenAI, Google Gemini, DeepSeek, and OpenRouter" width="799" height="410"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Over 20 LLM providers available at setup. Nous Portal is the default, bundling 300+ models with tool use included.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxe7mgz06bg1bo7rbng05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxe7mgz06bg1bo7rbng05.png" alt="Hermes Agent platform selection menu showing Telegram, Slack, Discord, WhatsApp, Email, Signal, and 15 more messaging platforms" width="800" height="463"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Platform selection covers Telegram, Slack, Discord, WhatsApp, email, Signal, and more. Telegram was the choice here for daily operational use.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F37trsrmm9osyg8wud6b6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F37trsrmm9osyg8wud6b6.png" alt="Hermes Agent tools selection showing web search, browser automation, file operations, code execution, memory, cron jobs, and more" width="800" height="511"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Tools enabled at setup: web search, file operations, code execution, persistent memory, cron jobs, cross-platform messaging, and task planning.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjnmr8al1uw4wt9ft5cp6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjnmr8al1uw4wt9ft5cp6.png" alt="Hermes Agent TTS provider selection with Microsoft Edge TTS selected as free recommended option" width="799" height="300"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;TTS is optional. Microsoft Edge TTS is free and needs no API key, a reasonable default for voice message support.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhkaxc6ffb3d4032qqx6b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhkaxc6ffb3d4032qqx6b.png" alt="Hermes Agent installation complete screen showing available commands: hermes, hermes setup, hermes config, hermes gateway install" width="800" height="508"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Installation complete. File paths are redacted. The next step is running hermes gateway install to set up the Telegram service.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxgjl1zx8ecjls59avrhu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxgjl1zx8ecjls59avrhu.png" alt="Hermes gateway installed as a systemd user service with linger enabled so it survives SSH logout" width="800" height="284"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The gateway runs as a systemd user service. Linger is enabled automatically so Hermes keeps running after SSH logout. No screen or tmux needed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvxa28bbifs8mldjzsmz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvxa28bbifs8mldjzsmz2.png" alt="Telegram userinfobot profile showing how to get your Telegram user ID for Hermes Agent setup" width="390" height="633"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;To lock Hermes to your account only, you need your Telegram user ID. @userinfobot gives it to you in one message.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Lock Telegram down before enabling server tools
&lt;/h2&gt;

&lt;p&gt;The setup wizard asks for a numeric Telegram user ID. That value is the sender allowlist, and it is different from a chat or group allowlist. In current Hermes configuration, the important setting for a private bot is &lt;code&gt;TELEGRAM_ALLOWED_USERS&lt;/code&gt; or its &lt;code&gt;allow_from&lt;/code&gt; equivalent in the active profile.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Use your own numeric ID from &lt;code&gt;/whoami&lt;/code&gt; or &lt;code&gt;@userinfobot&lt;/code&gt;, never the placeholder above. An empty &lt;code&gt;allowed_chats&lt;/code&gt; field by itself does not prove that the bot is open because it controls a different scope. Verify the effective sender allowlist instead: it should contain your ID, no wildcard, and no group IDs unless group access is intentional.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Live verification:&lt;/strong&gt; This deployment has exactly one sender in &lt;code&gt;TELEGRAM_ALLOWED_USERS&lt;/code&gt;, with no wildcard, guest mode, group allowlist, profile override, or systemd override. Its empty &lt;code&gt;allowed_chats&lt;/code&gt; value therefore does not let other Telegram users control Hermes. It only means the approved sender can reach the bot from any chat the bot has joined. Keep sensitive commands in the private DM because replies sent in a group remain visible to that group.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Back up &lt;code&gt;~/.hermes/.env&lt;/code&gt; and &lt;code&gt;config.yaml&lt;/code&gt; before changing gateway access.&lt;/li&gt;
&lt;li&gt;Keep the bot token and API keys out of screenshots, logs, shell history, and Git.&lt;/li&gt;
&lt;li&gt;Restart the gateway after an allowlist change, then confirm the active profile and effective authorization mode.&lt;/li&gt;
&lt;li&gt;Review gateway logs for unexpected sender or chat IDs. Rotate the bot token through BotFather if exposure is suspected.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Security warning:&lt;/strong&gt; Do not combine an Internet-reachable messaging bot with unrestricted &lt;code&gt;NOPASSWD: ALL&lt;/code&gt; sudo. Hermes documentation recommends passwordless sudo only for specific commands when messaging access genuinely needs it. A safer production layout runs the Telegram gateway as a dedicated non-root user or uses a sandboxed terminal backend, while full administration stays in an authenticated SSH or local CLI session.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The live setup in this case was rechecked on Hermes Agent v0.18.2 on July 18, 2026. See the official &lt;a href="https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/messaging/telegram.md" rel="noopener noreferrer"&gt;Telegram configuration guide&lt;/a&gt; for &lt;code&gt;TELEGRAM_ALLOWED_USERS&lt;/code&gt; and the &lt;a href="https://hermes-agent.nousresearch.com/docs/reference/faq" rel="noopener noreferrer"&gt;Hermes security and troubleshooting guide&lt;/a&gt; for the safer sudo pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does in practice
&lt;/h2&gt;

&lt;p&gt;After setup, Hermes is reachable on Telegram. The first interaction is straightforward: send it your business context and it saves it to persistent memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkwvfjm6avfr2nl8w0kt4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkwvfjm6avfr2nl8w0kt4.png" alt="Hermes Agent first Telegram message introducing itself as a self-hosted AI agent running on this machine" width="519" height="284"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;First response after gateway setup. Hermes confirms it is running on the machine and lists what it can do.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvmy3nlh05c89p0riy96g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvmy3nlh05c89p0riy96g.png" alt="Hermes Agent saving business context to persistent memory in Telegram: name, business, stack, infrastructure, and client profile" width="520" height="513"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Business context saved to memory on first session: name, business, tech stack, infrastructure, and client profile. This persists across all future sessions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F986jf73b5z0xjhzssz1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F986jf73b5z0xjhzssz1r.png" alt="Hermes Agent recalling saved business context after a fresh Telegram session with a different model, remembering name, business, stack, and client profile" width="539" height="347"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;After deleting the chat and switching to a different model, Hermes recalled the full business context from memory on the first message. This is the key difference from a managed AI tool.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The memory-context screenshot above is the most important one. The chat was deleted, the model was changed, and Hermes came back knowing who the user is and what they build. That is persistent memory working as intended.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What did not work
&lt;/h2&gt;

&lt;p&gt;DeepSeek was the first provider selected because of the low cost. It failed immediately with a provider error on every message. The gateway logs showed the API was returning empty responses. The actual reason turned out to be simple: the DeepSeek account balance was below $0.01, not enough to process even a test request.&lt;/p&gt;

&lt;p&gt;The current deployment now uses &lt;code&gt;deepseek-v4-pro&lt;/code&gt; through the direct DeepSeek API. With provider &lt;code&gt;deepseek&lt;/code&gt;, the clean model identifier is &lt;code&gt;deepseek-v4-pro&lt;/code&gt;. Repeating the provider prefix as &lt;code&gt;deepseek/deepseek-v4-pro&lt;/code&gt; can trigger a configuration warning even when requests still work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Falbmw82r0fm9cptxauo4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Falbmw82r0fm9cptxauo4.png" alt="Hermes Agent Telegram error: model provider failed after retries, check gateway logs for diagnostics" width="558" height="437"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Provider failure message in Telegram. The error handling is clean: Hermes surfaces the problem without exposing raw API details in the chat.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8up4kludb8enzf3dn9mz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8up4kludb8enzf3dn9mz.png" alt="DeepSeek API dashboard showing topped-up balance under one cent, the cause of provider failures" width="800" height="431"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Root cause: less than $0.01 balance on the DeepSeek account. Switching to Google Gemini free tier resolved it immediately.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Two other things worth knowing before setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The full setup wizard can loop back to the beginning if you navigate past the last step. There is no need to run through it again. Ctrl+C after the first pass exits cleanly and the configuration is already saved.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;uv.lock&lt;/code&gt; warning appears during installation on some Ubuntu versions. It is not critical. The installer falls back automatically and everything continues.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cost
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hermes Agent:&lt;/strong&gt; Free. MIT license, no subscription, no per-seat fee.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VPS:&lt;/strong&gt; About $5-7 per month on Contabo or a comparable provider. The same server can run n8n alongside Hermes without conflict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM tokens:&lt;/strong&gt; DeepSeek V4 Pro is usage-based. On July 18, 2026, the official direct API price was $0.003625 per million cached input tokens, $0.435 per million uncached input tokens, and $0.87 per million output tokens. Actual monthly cost depends on context size, tool output, and usage. Prices may change.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Model cost is not the only limit. Long conversations, repeated tool output, and large memory context can use more tokens than the visible Telegram message suggests. Check provider usage and keep only the tools and context the task needs. Confirm current prices on the &lt;a href="https://api-docs.deepseek.com/quick_start/pricing" rel="noopener noreferrer"&gt;official DeepSeek pricing page&lt;/a&gt; before choosing a model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are still deciding whether an AI agent is the right fit for your situation, the &lt;a href="https://floxolab.com/blog/ai-agents-for-business" rel="noopener noreferrer"&gt;AI agents for business guide&lt;/a&gt; covers the difference between chatbots, automation workflows, and agents, and when each one makes sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  When this makes sense vs Claude Projects
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Hermes when:&lt;/strong&gt; You want the assistant to remember your business context permanently, run scheduled tasks automatically, stay available 24/7 on your own infrastructure, and work through Telegram without opening a browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Claude Projects when:&lt;/strong&gt; You need a capable reasoning assistant for occasional deep work, research, or writing tasks. Claude Projects is faster to start, requires no server, and is better suited for tasks where raw model quality matters more than persistence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run both:&lt;/strong&gt; Hermes handles daily operations and scheduled tasks through Telegram. Claude Projects handles heavier analysis and writing work in the browser. They cover different parts of the workflow and do not overlap.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://floxolab.com/cases/hermes-agent-self-hosted-telegram" rel="noopener noreferrer"&gt;FloxoLab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Last verified: July 18, 2026.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>selfhosted</category>
      <category>automation</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Protect Your Automated Business Processes with n8n Error Workflows</title>
      <dc:creator>Stepan Nikonov</dc:creator>
      <pubDate>Mon, 13 Jul 2026 05:25:59 +0000</pubDate>
      <link>https://dev.to/floxolab/protect-your-automated-business-processes-with-n8n-error-workflows-moi</link>
      <guid>https://dev.to/floxolab/protect-your-automated-business-processes-with-n8n-error-workflows-moi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A simple 2-node n8n workflow can alert you in Telegram, Slack, Google Chat, email, or another team channel when an automation fails, so leads, reports, invoices, and AI workflows do not break silently.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Automation is useful only when someone knows it is working. A lead follow-up workflow can fail, a Google Sheets sync can stop, an AI email routing workflow can hit an API limit, a CRM update can break because one field changed. If the workflow fails quietly, the business process is no longer automated. It is just invisible.&lt;/p&gt;

&lt;p&gt;This is why every serious n8n workflow should have basic error handling. Not a complicated observability stack. Not an expensive monitoring tool. Just one small error workflow that sends an alert to the channel your team already checks when something breaks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The goal is simple:&lt;/strong&gt; protect automated business processes by turning silent workflow failures into visible alerts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For small businesses running automated operations, this is often the missing reliability layer. Teams build useful n8n workflows for leads, email, reports, bookings, invoices, and internal operations, but forget the one question that matters after launch: who knows when it fails?&lt;/p&gt;

&lt;h2&gt;
  
  
  The 2-node workflow
&lt;/h2&gt;

&lt;p&gt;The basic setup is intentionally small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error Trigger
-&amp;gt; Telegram, Slack, Google Chat, email, or webhook alert
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmgyjh7qa4xg6akinotra.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmgyjh7qa4xg6akinotra.webp" alt="n8n error workflow canvas with Error Trigger connected to Telegram Send Message" width="800" height="388"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The simplest error handler is just two nodes: Error Trigger receives the failed execution data, then your chosen messaging node sends the alert.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.errortrigger/" rel="noopener noreferrer"&gt;n8n Error Trigger&lt;/a&gt; starts an error workflow when another workflow fails. n8n passes useful error data into that workflow, including details about the failed workflow and execution. The next node sends the alert to the place where the responsible person will actually see it.&lt;/p&gt;

&lt;p&gt;You do not need an Edit Fields or Set node if your alert node can use the Error Trigger data directly. That is the cleanest version: Error Trigger into the message app. A formatting node is only useful when you want to rename fields, build a cleaner message once, or reuse the same prepared text in several alert destinations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs3bir70r9h8lti2afr6e.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs3bir70r9h8lti2afr6e.webp" alt="n8n Error Trigger node configuration for a workflow error alert" width="800" height="200"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Error Trigger is the start of the shared alert workflow. It receives the error context from another workflow when that workflow fails.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Choose the alert channel your team already uses
&lt;/h2&gt;

&lt;p&gt;I use Telegram because it is my main messenger. That matters, but Telegram is not the only option. The same pattern can send alerts to Slack, Google Chat, email, Microsoft Teams through a webhook, or another internal notification channel.&lt;/p&gt;

&lt;p&gt;n8n has built-in nodes for &lt;a href="https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.telegram/" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt;, &lt;a href="https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.slack/" rel="noopener noreferrer"&gt;Slack&lt;/a&gt;, and &lt;a href="https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlechat/" rel="noopener noreferrer"&gt;Google Chat&lt;/a&gt;. If the team uses something else, a webhook or email alert can still work. The important decision is not the app name. It is whether the alert lands where the owner, operator, or support person already pays attention.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why error alerts matter for business automation
&lt;/h2&gt;

&lt;p&gt;Workflow failures are not just technical events. They are operational events.&lt;/p&gt;

&lt;p&gt;If a lead capture workflow fails, a customer may never get a reply. If an invoice workflow fails, finance may miss a record. If an AI workflow fails, someone may assume a task was completed when it never ran. If a daily reporting workflow fails, the team may make decisions from stale data.&lt;/p&gt;

&lt;p&gt;That is the real risk of automation: not that it fails, but that it fails quietly.&lt;/p&gt;

&lt;p&gt;A small n8n Error Workflow helps with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;n8n workflow monitoring without a paid monitoring platform.&lt;/li&gt;
&lt;li&gt;Telegram, Slack, Google Chat, email, or webhook alerts for failed lead follow-up automations.&lt;/li&gt;
&lt;li&gt;Faster debugging for AI automation workflows with API calls.&lt;/li&gt;
&lt;li&gt;Visibility when Google Sheets, Airtable, Notion, CRM, Gmail, Slack, or webhook steps fail.&lt;/li&gt;
&lt;li&gt;Basic protection for automated business processes after launch.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What the alert should include
&lt;/h2&gt;

&lt;p&gt;The message does not need to be fancy. It needs to make the first response faster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;n8n workflow failed

Workflow: Lead Intake to Google Sheets
Failed node: HTTP Request - CRM update
Error: 401 Unauthorized
Execution: https://your-n8n-domain/workflow/...
Time: 2026-05-19 09:30 Asia/Manila

First check: credentials, API quota, or changed field mapping.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good alerts reduce guessing. The best version includes the workflow name, failed node, error message, execution URL, and timestamp. If the workflow supports an important business process, add a short note about what to check first. Once an alert lands, the next step is finding the cause, which is the whole of &lt;a href="https://floxolab.com/blog/n8n-debug-failed-workflows" rel="noopener noreferrer"&gt;how to debug failed n8n workflows&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiazrjus2z4tuo6167fxg.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiazrjus2z4tuo6167fxg.webp" alt="n8n Telegram node configured to send a workflow failure message" width="799" height="294"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;This example uses Telegram because it is my main messenger, but the same alert text can be sent through Slack, Google Chat, email, or a webhook.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this helps most
&lt;/h2&gt;

&lt;p&gt;This pattern is useful anywhere n8n is moving important information between tools.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lead capture automation:&lt;/strong&gt; form, Facebook lead, or website inquiry into Google Sheets, Airtable, Notion, or a CRM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email routing automation:&lt;/strong&gt; Gmail or inbox classification that sends sales, support, admin, or invoice messages to the right place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI automation workflows:&lt;/strong&gt; OpenAI, Claude, or other AI API calls that may fail from rate limits, invalid input, or service issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reporting workflows:&lt;/strong&gt; daily or weekly summaries sent to Telegram, Slack, Google Chat, email, or a dashboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operations workflows:&lt;/strong&gt; booking updates, payment checks, fulfillment steps, document generation, and internal handoffs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In all of these cases, the error workflow does not fix the failed automation by itself. It does something more basic and usually more valuable: it tells the right person fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to connect it in n8n
&lt;/h2&gt;

&lt;p&gt;Create one workflow whose first node is Error Trigger. Connect it directly to Telegram, Slack, Google Chat, email, or your chosen alert destination. If the message expression becomes too messy, add an optional Edit Fields node between them to shape the alert text.&lt;/p&gt;

&lt;p&gt;After that, open the workflow you want to protect and set its error workflow in the workflow settings. n8n documents this under &lt;a href="https://docs.n8n.io/flow-logic/error-handling/" rel="noopener noreferrer"&gt;error handling&lt;/a&gt;. Once configured, failed production executions can trigger the shared error handler.&lt;/p&gt;

&lt;p&gt;The practical setup looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the shared alert workflow: Error Trigger -&amp;gt; your messaging or webhook node.&lt;/li&gt;
&lt;li&gt;Save and activate the alert workflow.&lt;/li&gt;
&lt;li&gt;Open another workflow, such as a lead capture, email routing, AI draft, or reporting automation.&lt;/li&gt;
&lt;li&gt;Open that workflow's settings.&lt;/li&gt;
&lt;li&gt;Find the Error Workflow setting and select the shared alert workflow.&lt;/li&gt;
&lt;li&gt;Save the protected workflow.&lt;/li&gt;
&lt;li&gt;Repeat the same setting on any other production workflow that should alert you when it fails.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0m9cybois93f6kcrx9xz.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0m9cybois93f6kcrx9xz.webp" alt="n8n workflow settings showing a shared Error Workflow selected for failure alerts" width="800" height="399"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Each production workflow can point to the same shared error handler from its workflow settings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is why the pattern scales well. The alert workflow stays in one place, while many different n8n workflows can point to it from their settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdw4aia9te33hui8s6fgf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdw4aia9te33hui8s6fgf.webp" alt="Telegram alert message from an n8n workflow failure notification" width="415" height="127"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The result is intentionally simple: an alert in the place you already check. In my setup, that place is Telegram.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One shared error workflow can protect multiple automations. That is the nice part. You do not need to rebuild the same alert branch inside every workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this does not replace
&lt;/h2&gt;

&lt;p&gt;Error alerts are not the same as backups, server monitoring, credential management, or security hardening.&lt;/p&gt;

&lt;p&gt;An n8n Error Workflow tells you when an n8n workflow fails. It does not tell you that your VPS is down before n8n can run, that Cloudflare cannot reach the origin, or that your database backup failed. Those need separate checks.&lt;/p&gt;

&lt;p&gt;The right reliability setup is layered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Error Workflow for failed n8n executions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://floxolab.com/cases/website-uptime-monitoring-n8n" rel="noopener noreferrer"&gt;Website uptime workflow&lt;/a&gt; for HTTP 500, 522, timeout, or missing page content.&lt;/li&gt;
&lt;li&gt;Backups for n8n credentials, workflows, database, and environment configuration.&lt;/li&gt;
&lt;li&gt;Basic server hardening and firewall rules for self-hosted automation stacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The small reliability habit
&lt;/h2&gt;

&lt;p&gt;The best business automation is not the workflow with the most nodes. It is the workflow a team can trust, inspect, and recover when something goes wrong.&lt;/p&gt;

&lt;p&gt;A 2-node n8n Error Workflow is a small habit, but it changes the operating model. Instead of hoping that lead follow-up, email routing, AI tasks, and reporting workflows are still running, you get a direct chat alert when they need attention.&lt;/p&gt;

&lt;p&gt;That is enough to protect many automated business processes before they become silent operational problems.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I originally published this on my site, &lt;a href="https://floxolab.com" rel="noopener noreferrer"&gt;FloxoLab&lt;/a&gt;, where I document practical automation and technical SEO for small business in the Philippines. If a workflow here is useful for your team, &lt;a href="https://floxolab.com/#contact" rel="noopener noreferrer"&gt;get in touch&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>n8n</category>
      <category>automation</category>
      <category>devops</category>
      <category>nocode</category>
    </item>
    <item>
      <title>Website Uptime Monitoring with n8n</title>
      <dc:creator>Stepan Nikonov</dc:creator>
      <pubDate>Mon, 06 Jul 2026 01:21:10 +0000</pubDate>
      <link>https://dev.to/floxolab/website-uptime-monitoring-with-n8n-3c6g</link>
      <guid>https://dev.to/floxolab/website-uptime-monitoring-with-n8n-3c6g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A 4-node workflow checks your website every 5 minutes and sends a Telegram, Slack, or Google Chat alert the moment it goes down, so you find out before a customer does.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most small business websites do not go down often. But when they do, the owner usually finds out the wrong way: a message from a customer saying the site is not loading, or a drop in bookings that only becomes obvious the next day.&lt;/p&gt;

&lt;p&gt;A basic uptime monitoring workflow changes that. Instead of waiting for someone to notice, n8n checks your site on a schedule and sends a direct alert to the place you already look when something needs attention: Telegram, Slack, Google Chat, or email.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Alert&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Every 5 minutes&lt;/td&gt;
&lt;td&gt;HTTP GET + status code&lt;/td&gt;
&lt;td&gt;Telegram (or Slack / Google Chat)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The workflow
&lt;/h2&gt;

&lt;p&gt;The whole setup fits in four nodes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Schedule Trigger (every 5 min)
-&amp;gt; HTTP Request (GET your site)
-&amp;gt; IF (status code not 200?)
  -&amp;gt; true: send alert
  -&amp;gt; false: do nothing, site is up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl6duw0xol2bbg36je22z.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl6duw0xol2bbg36je22z.webp" alt="n8n uptime monitoring workflow canvas: Schedule Trigger, HTTP Request, IF node, Telegram alert" width="800" height="239"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The false path connects to nothing. The workflow only acts when there is a problem. No alert means the check passed.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How each node is configured
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The false path does nothing on purpose.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No alert means the site responded with 200. The workflow stays quiet until something actually breaks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Schedule Trigger:&lt;/strong&gt; set to every 5 minutes. That gives a maximum 5-minute window before an alert fires. A 1-minute interval would generate noise from transient blips that recover on their own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP Request:&lt;/strong&gt; method GET, URL is the site homepage or a lightweight status endpoint. Set a &lt;strong&gt;Timeout&lt;/strong&gt; of around 10 000 ms. If the server takes longer than 10 seconds to respond, it is effectively down for a real user. In Settings, enable &lt;strong&gt;Continue on Fail&lt;/strong&gt; so a completely unreachable server does not stop the workflow before it reaches the IF node.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IF node:&lt;/strong&gt; condition checks whether &lt;code&gt;statusCode&lt;/code&gt; is not equal to 200. True path triggers the alert. False path is left unconnected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Telegram node:&lt;/strong&gt; sends the alert message. n8n has native nodes for &lt;a href="https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.telegram/" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt;, &lt;a href="https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.slack/" rel="noopener noreferrer"&gt;Slack&lt;/a&gt;, and &lt;a href="https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlechat/" rel="noopener noreferrer"&gt;Google Chat&lt;/a&gt;. The channel matters less than whether the responsible person will actually see the message when it arrives.&lt;/p&gt;
&lt;h2&gt;
  
  
  The alert message
&lt;/h2&gt;

&lt;p&gt;The message uses node name referencing to pull the status code from the HTTP Request result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🔴 Site Down Alert

Site: yoursite.com
Status: {{ $('Check Site').item.json.statusCode ?? 'offline' }}
Time: {{ $now.toISO() }}

Checked by n8n monitoring workflow.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiv6qgkyaqj1zz65tnft4.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiv6qgkyaqj1zz65tnft4.webp" alt="Telegram alert messages from n8n uptime monitoring workflow showing site down notifications" width="403" height="507"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The alert fires in Telegram when the site check fails. Same pattern works in Slack, Google Chat, or email.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What to check when the alert fires
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare dashboard first.&lt;/strong&gt; Sometimes the origin is up but Cloudflare is returning a cached error or a 522. The dashboard shows recent errors and whether the issue is between Cloudflare and the origin.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open the site from a different network.&lt;/strong&gt; Rules out a local DNS or ISP issue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check the VPS or hosting control panel.&lt;/strong&gt; A crashed process, full disk, or out-of-memory condition takes the site down without an application-level error.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check the n8n execution log.&lt;/strong&gt; The HTTP Request output shows the exact status code and response body.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Monitoring multiple sites
&lt;/h2&gt;

&lt;p&gt;For several URLs, add a &lt;a href="https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitinbatches/" rel="noopener noreferrer"&gt;Loop Over Items&lt;/a&gt; node before the HTTP Request. Keep the URL list in a Code node or Google Sheets row, process each one at a time, and include the site URL in the alert message so you know which one triggered.&lt;/p&gt;

&lt;p&gt;For two or three sites, duplicating the workflow per site is simpler and easier to debug than building a loop.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This workflow handles HTTP-level availability. It complements, but does not replace, &lt;a href="https://floxolab.com/blog/n8n-error-workflow-telegram-alerts" rel="noopener noreferrer"&gt;n8n Error Workflow alerts&lt;/a&gt;, which protect your automations from failing silently. One watches the infrastructure, the other watches the workflows running on top of it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;I originally published this on my site, &lt;a href="https://floxolab.com" rel="noopener noreferrer"&gt;FloxoLab&lt;/a&gt;, where I document practical automation and technical SEO for small business in the Philippines. If a workflow here is useful for your team, &lt;a href="https://floxolab.com/#contact" rel="noopener noreferrer"&gt;get in touch&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>n8n</category>
      <category>automation</category>
      <category>monitoring</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to Debug Failed n8n Workflows: Step-by-Step Guide</title>
      <dc:creator>Stepan Nikonov</dc:creator>
      <pubDate>Sun, 28 Jun 2026 20:41:45 +0000</pubDate>
      <link>https://dev.to/floxolab/how-to-debug-failed-n8n-workflows-step-by-step-guide-fej</link>
      <guid>https://dev.to/floxolab/how-to-debug-failed-n8n-workflows-step-by-step-guide-fej</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A workflow failed. The execution log shows a red node, but the error message is not obvious. This guide covers where to look first, how to reload real data and rerun, and the five errors that cause most n8n failures.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most n8n failures are not mysterious. They repeat the same patterns: a credential expired, an expression pointed to the wrong field, a webhook URL was the test one instead of the production one. The hard part is knowing where to start when all you see is a red node and a generic error message.&lt;/p&gt;

&lt;p&gt;This guide walks through the tools n8n gives you for debugging, the five errors that cover most real-world failures, and two nodes that help you handle failures more intentionally going forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Start with Execution History
&lt;/h2&gt;

&lt;p&gt;Every time a workflow runs, n8n records the execution: what data came in, what each node did, and where it stopped. This is the first place to go after a failure.&lt;/p&gt;

&lt;p&gt;Open the workflow and select the &lt;strong&gt;Executions&lt;/strong&gt; tab at the top. You will see a list of past runs with their status: Success, Failed, or Waiting. Select a failed one to open it.&lt;/p&gt;

&lt;p&gt;Inside the execution view you can see the canvas in its failed state: the node that caused the failure is marked in red, and the bottom panel shows the error message and the log. This tells you which node broke and what the error was, before you touch anything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3uch0qegiymjmzp5n0vh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3uch0qegiymjmzp5n0vh.png" alt="n8n Executions tab showing a failed execution with the error details panel and the Debug in editor button in the top right corner" width="800" height="489"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Executions tab shows past runs with their status. Open a failed execution to see which node broke, read the error message in the log panel, and find the Debug in editor button in the top right corner.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Read the error message before doing anything else. Many failures explain themselves: "401 Unauthorized", "Cannot read properties of undefined", "The provided authorization grant is invalid". The node name plus the error text is usually enough to know what went wrong.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Debug in Editor: reload real data and rerun
&lt;/h2&gt;

&lt;p&gt;Once you understand what failed, use the &lt;strong&gt;Debug in editor&lt;/strong&gt; button. This loads the actual input data from the failed execution into your current canvas. You can then make changes to the broken node and rerun the workflow using the same real data, without needing to trigger a new event.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8oz7rzrrxasmex4ki10o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8oz7rzrrxasmex4ki10o.png" alt="n8n editor canvas with execution data loaded from a failed run, showing the error in the bottom panel" width="800" height="434"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;After clicking Debug in editor, the canvas loads the data from the failed execution. Fix the broken node and rerun with the same real input. No need to trigger a new event.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is especially useful for workflows triggered by external events: a form submission, a webhook call, or an email. Reproducing that exact input manually takes time. Debug in Editor gives you the original payload immediately.&lt;/p&gt;

&lt;p&gt;For successful executions, the same panel offers &lt;strong&gt;Copy to editor&lt;/strong&gt; instead. That is useful when you want to test changes against a known-good input rather than a failed one.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Retry a past execution
&lt;/h2&gt;

&lt;p&gt;If you only need to run the failed execution again, you do not have to open the editor at all. n8n can rerun a past execution directly from the Executions tab, reusing the exact input data from the original run.&lt;/p&gt;

&lt;p&gt;Hover over a failed execution in the list, or open it, and use the retry option. n8n gives you two choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Retry with original workflow:&lt;/strong&gt; runs the execution again using the workflow exactly as it was when it first ran. Use this when the failure was temporary, like a rate limit or a service that was briefly down, and the workflow itself did not need changing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retry with currently saved workflow:&lt;/strong&gt; runs the same input data through the latest saved version of the workflow. Use this after you have fixed the broken node, to confirm the fix against the data that originally failed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both options reuse the original trigger data from that execution, so you do not need to resend the webhook, resubmit the form, or wait for the next scheduled run. The retry appears as a new entry in the Executions list.&lt;/p&gt;

&lt;p&gt;Retry is the fastest way to rerun an execution when you already know the cause. Debug in Editor is the better choice when you still need to inspect the data and change a node before running it again.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. The 5 most common errors
&lt;/h2&gt;

&lt;p&gt;These five patterns account for most of the failures you will actually see in production n8n workflows.&lt;/p&gt;
&lt;h3&gt;
  
  
  Credential or auth error (401, 403)
&lt;/h3&gt;

&lt;p&gt;The node could not authenticate with the external service. Common causes: the credential expired, the API key was regenerated, OAuth tokens were revoked, or the connected account lost the required permissions.&lt;/p&gt;

&lt;p&gt;Fix: open the node settings and re-test the credential. If it fails the test, reconnect or regenerate it in the credentials panel. For OAuth-based services like Gmail or Google Sheets, you may need to re-authorize from scratch.&lt;/p&gt;

&lt;p&gt;A 403 is slightly different: the credential is valid but the account does not have permission to perform that specific action. Check the API scopes or the account's role in the connected service.&lt;/p&gt;
&lt;h3&gt;
  
  
  Expression error (undefined, wrong syntax)
&lt;/h3&gt;

&lt;p&gt;An expression in a field is referencing a value that does not exist. The result shows &lt;code&gt;[undefined]&lt;/code&gt; or the workflow throws a "Cannot read properties of undefined" error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjs6ul6orp7kldas1g69r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjs6ul6orp7kldas1g69r.png" alt="n8n expression editor showing undefined result for a field path that does not exist in the input data" width="780" height="246"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The expression editor shows [undefined] when the referenced field path does not exist in the input data. Open the left panel to inspect what fields are actually available.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Fix: click on the broken field to open the expression editor. On the left panel, expand the input data from the previous node and check the actual field names and structure. A common mistake is using &lt;code&gt;{{ $json.name }}&lt;/code&gt; when the real field is nested: &lt;code&gt;{{ $json.contact.name }}&lt;/code&gt;. Use the field browser to drag the correct path into the expression.&lt;/p&gt;
&lt;h3&gt;
  
  
  Webhook not firing (test URL vs production URL)
&lt;/h3&gt;

&lt;p&gt;The workflow is active, the external service is configured, but no data arrives. This is almost always a test URL vs production URL mismatch.&lt;/p&gt;

&lt;p&gt;n8n gives each webhook two URLs: one for testing (only works while the workflow is open in the editor), and one for production (only works when the workflow is active). If you configured your external service with the test URL and then activated the workflow, nothing will arrive because the test URL stops listening once you close the editor.&lt;/p&gt;

&lt;p&gt;Both URLs are visible directly inside the Webhook node settings. Many people only notice the first one. The test URL is shown at the top; the production URL is listed below it. Copy the production URL and update it in the external service, then test by triggering the actual event from that service.&lt;/p&gt;
&lt;h3&gt;
  
  
  API timeout or rate limit (429)
&lt;/h3&gt;

&lt;p&gt;The HTTP Request node or an API-connected node stops responding. You may see a 429 Too Many Requests error, or the execution simply times out.&lt;/p&gt;

&lt;p&gt;n8n's default HTTP Request node timeout is 5 minutes (300,000 ms), but many workflows hit limits earlier because the external API enforces its own rate limits or because a slow response blocks the execution. A 429 means you are sending too many requests too fast.&lt;/p&gt;

&lt;p&gt;Fix for rate limits: add a Wait node between batched requests to slow down the pace. Fix for timeouts: check whether the external API is responding at all (test it directly in a browser or with a manual HTTP call), then increase the timeout in the HTTP Request node settings if the service is just slow.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data type mismatch (array vs object, null values)
&lt;/h3&gt;

&lt;p&gt;A node expects a single object but receives an array, or a field contains null and the next expression tries to read a property from it. This often surfaces as "Cannot read properties of null" or unexpected behavior where only the first item is processed.&lt;/p&gt;

&lt;p&gt;Fix: use the Input panel to inspect what the previous node actually returned. If it returned an array when you expected an object, add a Split Out node to break it into individual items before processing. If null values cause crashes, add an IF node upstream to filter them out before they reach the sensitive step.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Enable debug logging (self-hosted only)
&lt;/h2&gt;

&lt;p&gt;If you run &lt;a href="https://floxolab.com/cases/self-hosted-n8n-deployment-docker-cloudflare" rel="noopener noreferrer"&gt;n8n on a self-hosted VPS&lt;/a&gt; and the execution log does not give enough detail, you can turn on verbose logging by setting &lt;code&gt;N8N_LOG_LEVEL=debug&lt;/code&gt; in your &lt;code&gt;.env&lt;/code&gt; file and restarting the container.&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="nv"&gt;N8N_LOG_LEVEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;debug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With debug logging active, the server logs include detailed HTTP request and response data, credential resolution steps, and node input/output at each stage. This is useful for intermittent failures that are hard to reproduce by opening the editor: connection timeouts, credential handshake errors, and SSL issues tend to surface in the logs before they appear clearly in the execution view.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Reset after debugging.&lt;/strong&gt; Debug output is verbose and will fill disk space quickly on a small VPS. Set &lt;code&gt;N8N_LOG_LEVEL=info&lt;/code&gt; or remove the variable once you have found what you needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  6. The Debug Helper node
&lt;/h2&gt;

&lt;p&gt;Most n8n users do not know this node exists. The Debug Helper is a built-in utility node that lets you deliberately trigger different error types or generate random test data inside a workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2bfke8ndyco5ve736hqd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2bfke8ndyco5ve736hqd.png" alt="n8n Debug Helper node settings showing the category options: Do Nothing, Throw Error, Out Of Memory, Generate Random Data" width="780" height="301"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Debug Helper node has four modes. Throw Error is useful for testing your error workflow before real failures happen in production.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The four modes are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Do Nothing:&lt;/strong&gt; passes through without doing anything. Useful as a placeholder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throw Error:&lt;/strong&gt; deliberately fails the workflow with a message you specify. Use this to test your error handling before a real failure happens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Out Of Memory:&lt;/strong&gt; generates a large memory allocation to simulate an out-of-memory error. Useful for stress-testing self-hosted setups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate Random Data:&lt;/strong&gt; produces random structured data. Useful when you need test input but do not have a real event to trigger the workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most practical use of Debug Helper for most workflows: add it temporarily before your error-handling path and set it to Throw Error. This lets you verify that your Error Workflow actually fires and sends the alert before you see a real failure in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Stop And Error: controlled failures with clear messages
&lt;/h2&gt;

&lt;p&gt;Sometimes a workflow should stop not because something broke unexpectedly, but because the data does not meet a condition you care about. An empty response from an API, a missing required field, a contact that should not be there. Without explicit handling, the workflow either completes silently or fails with a confusing message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foi3n2l1b2l5w2dnoysvw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foi3n2l1b2l5w2dnoysvw.png" alt="n8n Stop and Error node configured with Error Message type and a custom error message" width="780" height="205"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Stop and Error lets you define exactly when and why a workflow should fail, with a message that makes the cause clear in the execution log and in any error alerts.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Stop And Error node ends the workflow at that point and marks the execution as failed, with the message you provide. Two error types are available: Error Message (a plain text string) or Error Object (a JSON object with structured error properties).&lt;/p&gt;

&lt;p&gt;Used with an IF node upstream, this gives you intentional failure points. The workflow says "no valid email found, stopping here" instead of crashing three nodes later with a cryptic null reference. When that controlled failure triggers your error alert, the message is already readable.&lt;/p&gt;

&lt;p&gt;Stop And Error can only be placed as the last node in a workflow branch. It is not a mid-flow control node.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect failures to alerts
&lt;/h2&gt;

&lt;p&gt;Debugging after a failure is reactive. The better habit is knowing about failures before someone else does.&lt;/p&gt;

&lt;p&gt;n8n's Error Trigger runs a separate workflow when any production workflow fails. That separate workflow sends an alert to Telegram, Slack, Google Chat, email, or wherever your team already pays attention. For small businesses in the Philippines and anywhere else running automated operations, this is the layer that turns silent failures into visible ones. The execution log gives you the workflow name, failed node, error message, and a link back to the execution.&lt;/p&gt;

&lt;p&gt;The full setup, including what the alert should contain and how to point multiple workflows at a single shared error handler, is covered in the &lt;a href="https://floxolab.com/blog/n8n-error-workflow-telegram-alerts" rel="noopener noreferrer"&gt;n8n error workflow and chat alerts guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  n8n rerun and retry: common questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How do I rerun a failed execution in n8n?
&lt;/h3&gt;

&lt;p&gt;Open the Executions tab, hover over the failed run, and choose a retry option. Retry with original workflow reruns it exactly as it was; Retry with currently saved workflow runs the same input through your latest saved version. Both reuse the original trigger data, so you do not need to trigger the workflow again.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between Retry with original workflow and Retry with currently saved workflow?
&lt;/h3&gt;

&lt;p&gt;Retry with original workflow runs the execution using the workflow exactly as it was when it first ran, which suits temporary failures like rate limits or a service that was briefly down. Retry with currently saved workflow runs the same input through the latest saved version, which is what you want after fixing the broken node.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does retrying an n8n execution reuse the original data?
&lt;/h3&gt;

&lt;p&gt;Yes. Both retry options replay the original trigger and input data from the failed execution. You do not need to resend a webhook, resubmit a form, or wait for the next scheduled run.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I rerun an n8n workflow from a specific node?
&lt;/h3&gt;

&lt;p&gt;Use Debug in editor to load the failed execution's data onto the canvas, then run a single node or the steps after it without retriggering the whole workflow. This is the better option when you need to change a node before running it again.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I originally published this on my site, &lt;a href="https://floxolab.com" rel="noopener noreferrer"&gt;FloxoLab&lt;/a&gt;, where I document practical automation and technical SEO for small business in the Philippines. If a workflow here is useful for your team, &lt;a href="https://floxolab.com/#contact" rel="noopener noreferrer"&gt;get in touch&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>n8n</category>
      <category>automation</category>
      <category>debugging</category>
      <category>nocode</category>
    </item>
    <item>
      <title>Self-hosted n8n Deployment with Docker, Cloudflare, and PostgreSQL</title>
      <dc:creator>Stepan Nikonov</dc:creator>
      <pubDate>Mon, 22 Jun 2026 21:02:12 +0000</pubDate>
      <link>https://dev.to/floxolab/self-hosted-n8n-deployment-with-docker-cloudflare-and-postgresql-3efn</link>
      <guid>https://dev.to/floxolab/self-hosted-n8n-deployment-with-docker-cloudflare-and-postgresql-3efn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A private automation server setup for real workflows: domain, Cloudflare proxy, VPS, Docker, n8n, PostgreSQL, HTTPS, and basic hardening.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This setup gives n8n a private place to run real automations: a domain behind Cloudflare, a VPS running Docker, PostgreSQL for workflow data, HTTPS for the editor, and backups to Google Drive. It is the infrastructure layer behind form workflows, chatbots, API jobs, and internal tools.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Domain to Cloudflare to VPS to Docker to n8n.&lt;/strong&gt;&lt;br&gt;
Public traffic, containers, workflow logic, and storage are separated into clear layers so the automation workspace is easier to inspect, restart, and maintain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Public layer&lt;/td&gt;
&lt;td&gt;Domain, Cloudflare proxy, HTTPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;VPS at about $7/mo, around PHP 430&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workflow layer&lt;/td&gt;
&lt;td&gt;30+ workflows in the workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why this setup
&lt;/h2&gt;

&lt;p&gt;A default n8n install can be useful for testing, but a real automation workspace needs a little more structure. The goal here was to make the server usable for private workflows, webhooks, form automations, API jobs, and internal bots while keeping the public surface understandable.&lt;/p&gt;

&lt;p&gt;Cloudflare sits in front of the domain, HTTPS is enforced in the browser, Docker keeps services isolated and restartable, and PostgreSQL gives n8n a proper database layer instead of treating the server as a disposable demo.&lt;/p&gt;

&lt;p&gt;This setup runs on a VPS that costs about $7 per month, roughly PHP 430, which is enough for a focused workspace with dozens of small workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proof screenshots
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9l90ll06e6aodzr0ciyo.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9l90ll06e6aodzr0ciyo.webp" alt="Cloudflare DNS records with proxied status enabled and sensitive IP content hidden" width="800" height="328"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Cloudflare DNS proxy is enabled so the public entry point is not a raw VPS port. IP values are hidden.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fge1ruzodxdv5e8e4ven1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fge1ruzodxdv5e8e4ven1.png" alt="Docker ps output showing n8n and PostgreSQL containers running with healthy status" width="799" height="235"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;n8n and PostgreSQL run as Docker services with multi-day uptime. PostgreSQL was added later, so its uptime can be newer than other services.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffbcilimk60dj40nvd69h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffbcilimk60dj40nvd69h.png" alt="n8n dashboard with multiple real workflow rows in a private automation workspace" width="800" height="438"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A private n8n workspace with 30+ workflows across drafts, prototypes, and live automations.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqkn00nt5ftyyav9wcslt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqkn00nt5ftyyav9wcslt.png" alt="Browser security panel showing a secure HTTPS connection for the n8n domain" width="331" height="283"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;HTTPS is active for the n8n domain. The admin path is hidden in the screenshot.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What was configured
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain and proxy&lt;/strong&gt; — Cloudflare DNS and proxy are used in front of the VPS, with sensitive origin details hidden from public screenshots.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker runtime&lt;/strong&gt; — n8n and supporting services run as containers so the stack can be restarted, inspected, and extended without mixing every service directly into the host.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL&lt;/strong&gt; — added as the database layer for n8n. The container is newer because it was introduced as a setup refinement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS&lt;/strong&gt; — the workflow UI loads over HTTPS, so operators are not using the admin surface over plain HTTP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic hardening&lt;/strong&gt; — small-business practical hardening: Cloudflare in front, HTTPS enforced, firewall rules for required access, and backups rather than an open default install.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This is not described as enterprise infrastructure. It is a practical self-hosted automation foundation for small workflows and internal tools, with the sensitive details removed from public screenshots.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Good fits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Owner-run operations&lt;/strong&gt; — a small business that wants leads, forms, email drafts, and internal alerts running from one private n8n workspace instead of scattered one-off tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VA and service teams&lt;/strong&gt; — a VA agency or ops team running several client intake workflows from one server, with separate workflows for forms, CRM updates, reports, and review queues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhook-heavy tools&lt;/strong&gt; — teams that need stable public endpoints for website forms, chatbots, payment events, WooCommerce actions, Airtable updates, or Google Workspace jobs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zapier-style migration&lt;/strong&gt; — teams moving recurring automations into a private workflow engine where the logic is visible, documented, and easier to inspect before scaling further.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Backup and maintenance layer
&lt;/h2&gt;

&lt;p&gt;The server and n8n setup already have backups going to Google Drive. That matters because a self-hosted automation server is not only about getting n8n online. It also needs a way to recover workflows, credentials, and service data if an update, server issue, or configuration mistake breaks something.&lt;/p&gt;

&lt;p&gt;The maintenance plan is simple: keep restore steps, update notes, and basic monitoring close to the deployment so the setup is easier to maintain over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related guide
&lt;/h2&gt;

&lt;p&gt;Self-hosting changes the cost math against managed tools. For a side-by-side on what each option actually costs, read &lt;a href="https://floxolab.com/blog/zapier-vs-make-vs-n8n-pricing" rel="noopener noreferrer"&gt;Zapier vs Make vs n8n Pricing: A Real Lead Form Example&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I originally published this on my site, &lt;a href="https://floxolab.com" rel="noopener noreferrer"&gt;FloxoLab&lt;/a&gt;, where I document practical automation and technical SEO for small business in the Philippines. If you already have a VPS and need n8n configured properly (domain, Cloudflare, Docker, HTTPS, PostgreSQL, backups, handover notes), &lt;a href="https://floxolab.com/#contact" rel="noopener noreferrer"&gt;get in touch&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>n8n</category>
      <category>docker</category>
      <category>automation</category>
      <category>selfhosted</category>
    </item>
  </channel>
</rss>
