<?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: Tj Thouhid</title>
    <description>The latest articles on DEV Community by Tj Thouhid (@tjthouhid).</description>
    <link>https://dev.to/tjthouhid</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%2F4189581%2F853516e1-cd3e-46e5-a430-ed6a8995848a.jpg</url>
      <title>DEV Community: Tj Thouhid</title>
      <link>https://dev.to/tjthouhid</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tjthouhid"/>
    <language>en</language>
    <item>
      <title>Port already in use? How to fix it when your AI coding agent keeps starting servers</title>
      <dc:creator>Tj Thouhid</dc:creator>
      <pubDate>Wed, 21 Oct 2026 12:41:22 +0000</pubDate>
      <link>https://dev.to/tjthouhid/port-already-in-use-how-to-fix-it-when-your-ai-coding-agent-keeps-starting-servers-11kl</link>
      <guid>https://dev.to/tjthouhid/port-already-in-use-how-to-fix-it-when-your-ai-coding-agent-keeps-starting-servers-11kl</guid>
      <description>&lt;p&gt;You ask your AI coding agent to run the app, and you get this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: listen EADDRINUSE: address already in use :::3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or worse, you don't get an error at all. The agent's server quietly starts on 3001, your browser is still on 3000, and you spend ten minutes wondering why your change isn't showing up.&lt;/p&gt;

&lt;p&gt;I wrote a general guide to &lt;a href="https://dev.to/tjthouhid/whats-using-port-3000-on-my-mac-find-it-see-who-started-it-and-stop-it-safely-5h0i"&gt;finding and stopping whatever is using port 3000 on a Mac&lt;/a&gt;. This post is about the version of the problem that AI agents cause, because it happens a lot more often now, and it's easy to prevent once you know why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI agents leave servers running
&lt;/h2&gt;

&lt;p&gt;Claude Code, Cursor, Codex and similar tools all run shell commands for you. That's useful, but dev servers are a bad fit for how they work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Background servers.&lt;/strong&gt; A dev server never finishes, so agents often start it in the background, check that the page loads, and move on. Nothing tells them to stop it later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Re-runs.&lt;/strong&gt; Later in the same session, or in a new session, the agent wants to test again. It doesn't know a server is already running, so it starts another one. Many dev servers (Vite, for example) quietly move to the next free port, so you end up with copies on 3000, 3001 and 3002.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crashed or closed sessions.&lt;/strong&gt; If the agent's session crashes, or you close the window, the server it started can keep running with no parent. On macOS it gets adopted by &lt;code&gt;launchd&lt;/code&gt; and just sits there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Several agents at once.&lt;/strong&gt; Two agents on one project both want the same port. The second one either fails or picks a random port.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the fix has two parts: clean up what's running now, then stop it happening again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: find what's listening on the port
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsof &lt;span class="nt"&gt;-nP&lt;/span&gt; &lt;span class="nt"&gt;-iTCP&lt;/span&gt;:3000 &lt;span class="nt"&gt;-sTCP&lt;/span&gt;:LISTEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-iTCP:3000&lt;/code&gt; looks only at TCP on port 3000.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-sTCP:LISTEN&lt;/code&gt; shows only the process that's listening, which is the one holding the port. Without it you'd also see your browser's connections.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-n&lt;/code&gt; and &lt;code&gt;-P&lt;/code&gt; skip name lookups, so it's faster and shows &lt;code&gt;3000&lt;/code&gt; instead of a service name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll get something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
node    48213 tj     23u  IPv6  0x...       0t0  TCP *:3000 (LISTEN)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To see every listening port at once, which is handy after a long agent session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsof &lt;span class="nt"&gt;-nP&lt;/span&gt; &lt;span class="nt"&gt;-iTCP&lt;/span&gt; &lt;span class="nt"&gt;-sTCP&lt;/span&gt;:LISTEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: check what it is and who started it
&lt;/h2&gt;

&lt;p&gt;Before you stop anything, find out what it is. Take the PID and ask &lt;code&gt;ps&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-o&lt;/span&gt; pid,ppid,etime,command &lt;span class="nt"&gt;-p&lt;/span&gt; 48213
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  PID  PPID  ELAPSED COMMAND
48213     1 01:12:40 node /Users/you/code/shop/node_modules/.bin/vite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;command&lt;/strong&gt; shows the full command line, which usually includes the project folder. That tells you which project it belongs to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;etime&lt;/strong&gt; (shown as ELAPSED) is how long it's been running. An hour means it's not the server you just started.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ppid&lt;/strong&gt; is the parent process. Run the same &lt;code&gt;ps&lt;/code&gt; command on that PID to see what launched it. You'll often find a shell that belongs to your editor or AI tool. If the PPID is &lt;code&gt;1&lt;/code&gt;, the thing that started it has already gone, and this is a leftover.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it's a database, Docker or something you didn't expect, stop and think before going further.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: stop it safely
&lt;/h2&gt;

&lt;p&gt;Ask it to quit first:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This sends SIGTERM, a polite "please quit", so the server can close files and connections properly. Wait a couple of seconds and run the &lt;code&gt;lsof&lt;/code&gt; command from step 1 again.&lt;/p&gt;

&lt;p&gt;Only if it's still there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; 48213
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;kill -9&lt;/code&gt; ends it straight away with no cleanup. Use it second, not first.&lt;/p&gt;

&lt;p&gt;If you're sure the listener on 3000 is a leftover dev server and want one line, this stops only the process that's listening on that port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;lsof &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nt"&gt;-iTCP&lt;/span&gt;:3000 &lt;span class="nt"&gt;-sTCP&lt;/span&gt;:LISTEN&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-sTCP:LISTEN&lt;/code&gt; part matters. Without it, &lt;code&gt;lsof&lt;/code&gt; also returns other processes connected to the port, such as your browser, and you'd send them the signal too.&lt;/p&gt;

&lt;p&gt;If the server comes straight back after you stop it, something is restarting it, such as Docker, a process manager or a tool like Laravel Herd. Stop it there instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: stop it happening again
&lt;/h2&gt;

&lt;p&gt;Cleaning up is fine once. Doing it every day gets old. These changes made the biggest difference for me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Give each agent a fixed port.&lt;/strong&gt; Put it in the project's &lt;code&gt;.env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And make the dev server fail instead of drifting to a random port. For Vite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--port&lt;/span&gt; 3001 &lt;span class="nt"&gt;--strictPort&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A server that fails loudly on a busy port is much easier to deal with than one that silently moves to 3004.&lt;/p&gt;

&lt;p&gt;If you run more than one agent on the same project, give each one its own folder (a git worktree) and its own port, so they never compete for 3000.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write the rules down for the agent.&lt;/strong&gt; Agents read &lt;code&gt;CLAUDE.md&lt;/code&gt; (Claude Code) or &lt;code&gt;AGENTS.md&lt;/code&gt; (Codex and others). Add a short section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Dev server&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Run it with: &lt;span class="sb"&gt;`npm run dev -- --port 3001 --strictPort`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use port 3001 only.
&lt;span class="p"&gt;-&lt;/span&gt; Before starting a server, check if one is already running:
  &lt;span class="sb"&gt;`lsof -nP -iTCP:3001 -sTCP:LISTEN`&lt;/span&gt;. If it is, reuse it.
&lt;span class="p"&gt;-&lt;/span&gt; Stop any server you started when the task is done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one change cut my duplicate servers by more than anything else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop servers when you're done.&lt;/strong&gt; At the end of a session, ask the agent to stop what it started, or run &lt;code&gt;lsof -nP -iTCP -sTCP:LISTEN&lt;/code&gt; yourself and clear out anything left over. It takes ten seconds and saves the confusing "why is my old code showing?" moment the next morning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doing this in Lokstack
&lt;/h2&gt;

&lt;p&gt;Disclosure: I build Lokstack, a Mac app, and this part is about my own app.&lt;/p&gt;

&lt;p&gt;I got tired of running these commands after every agent session, so Lokstack does the looking for you. Search for a port and it shows what's using it, which project it belongs to and who started it. &lt;strong&gt;Stop&lt;/strong&gt; asks the program to quit, like &lt;code&gt;kill&lt;/code&gt;. &lt;strong&gt;Force&lt;/strong&gt; stops it straight away, like &lt;code&gt;kill -9&lt;/code&gt;. The Agents screen has a &lt;strong&gt;Left running&lt;/strong&gt; panel that lists the dev servers AI tools started and didn't stop. All of that is on the free plan.&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%2F59xk9c3uiy9gfs1oydgr.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%2F59xk9c3uiy9gfs1oydgr.png" alt="Lokstack Ports screen showing who owns each port, with Stop and Force buttons" width="800" height="800"&gt;&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%2Frk27em4c2cw4vovav58c.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%2Frk27em4c2cw4vovav58c.png" alt="Lokstack Left running panel listing servers AI tools forgot to stop" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a short video of finding and freeing a busy port:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/OCykVC-UTv4" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you'd rather stay in Terminal, the commands above are all you need. &lt;a href="https://lokstack.app" rel="noopener noreferrer"&gt;https://lokstack.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's the most servers you've found an agent left running? Tell me in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>macos</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to run multiple AI coding agents on one Mac without port clashes</title>
      <dc:creator>Tj Thouhid</dc:creator>
      <pubDate>Wed, 21 Oct 2026 12:40:16 +0000</pubDate>
      <link>https://dev.to/tjthouhid/how-to-run-multiple-ai-coding-agents-on-one-mac-without-port-clashes-3b0f</link>
      <guid>https://dev.to/tjthouhid/how-to-run-multiple-ai-coding-agents-on-one-mac-without-port-clashes-3b0f</guid>
      <description>&lt;p&gt;Running one AI coding agent on a project is easy. Running two or three at once on the same Mac is where it gets messy. I've had Claude Code fixing a bug while Codex worked on a feature in the same repo, and an hour later I found two dev servers on two ports, a branch with both agents' changes mixed together, and test data in my local database that neither of them should have touched.&lt;/p&gt;

&lt;p&gt;None of this is the agents' fault. They're all working in one shared place. The fix is to give each agent its own space. Here's how I set that up by hand, with plain commands, and what to clean up afterwards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why agents collide
&lt;/h2&gt;

&lt;p&gt;When two agents work on one project, they usually share five things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The same branch and working tree.&lt;/strong&gt; Both agents edit the same files on disk. One agent's half-finished change breaks the other agent's test run, and the commit history ends up a mix of both.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The same dev server port.&lt;/strong&gt; Each agent runs &lt;code&gt;npm run dev&lt;/code&gt; to check its work. The first one gets port 3000. The second one either fails with &lt;code&gt;EADDRINUSE&lt;/code&gt; or quietly moves to 3001, and then you're not sure which browser tab is showing whose code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The same database.&lt;/strong&gt; One agent runs a migration or seeds data, and the other agent's tests start failing for reasons that have nothing to do with its own change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The same &lt;code&gt;.env&lt;/code&gt; file.&lt;/strong&gt; If one agent changes a setting to test something, every other agent gets that change too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leftover servers.&lt;/strong&gt; Agents often start a server in the background and never stop it. After a few sessions you have old copies of your app running on ports you didn't pick.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So the goal is simple: one branch, one folder, one port, one database and one &lt;code&gt;.env&lt;/code&gt; per agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: one git worktree per agent
&lt;/h2&gt;

&lt;p&gt;A git worktree is a second (or third) folder that's linked to the same repository but checked out on its own branch. Each agent gets its own folder, so they never edit the same files on disk.&lt;/p&gt;

&lt;p&gt;From your main project folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git worktree add ../shop-claude &lt;span class="nt"&gt;-b&lt;/span&gt; agent/claude-fix-cart
git worktree add ../shop-codex  &lt;span class="nt"&gt;-b&lt;/span&gt; agent/codex-search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;shop/&lt;/code&gt; on your main branch (yours)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shop-claude/&lt;/code&gt; on &lt;code&gt;agent/claude-fix-cart&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shop-codex/&lt;/code&gt; on &lt;code&gt;agent/codex-search&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open each agent in its own folder. To see what you have at any time:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Two things catch people out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ignored files are not copied.&lt;/strong&gt; A new worktree has no &lt;code&gt;node_modules&lt;/code&gt;, no &lt;code&gt;.env&lt;/code&gt; and no local database file. Run &lt;code&gt;npm install&lt;/code&gt; (or your package manager) in each one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One branch can only be checked out in one worktree.&lt;/strong&gt; That's a good thing. It stops two agents from working on the same branch by accident.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: a fixed port per agent
&lt;/h2&gt;

&lt;p&gt;Give each worktree its own port and tell the agent about it. Most frameworks read a &lt;code&gt;PORT&lt;/code&gt; value or take a flag.&lt;/p&gt;

&lt;p&gt;For Next.js and many Node servers, &lt;code&gt;PORT&lt;/code&gt; is enough:&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="c"&gt;# in shop-claude/&lt;/span&gt;
&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3001 npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Vite, pass the port and make it fail instead of quietly picking another one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--port&lt;/span&gt; 3002 &lt;span class="nt"&gt;--strictPort&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--strictPort&lt;/code&gt; matters. Without it, Vite moves to the next free port, which is exactly how you end up with mystery servers on 3003 and 3004.&lt;/p&gt;

&lt;p&gt;I keep a tiny table in my notes: main is 3000, Claude is 3001, Codex is 3002. Boring, but it means I always know which tab is which.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: a database copy per agent
&lt;/h2&gt;

&lt;p&gt;If your agents run migrations or write test data, give each one its own copy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Postgres.&lt;/strong&gt; &lt;code&gt;createdb&lt;/code&gt; can copy an existing database as a template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;createdb &lt;span class="nt"&gt;-T&lt;/span&gt; shop_dev shop_claude
createdb &lt;span class="nt"&gt;-T&lt;/span&gt; shop_dev shop_codex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This only works when nothing is connected to &lt;code&gt;shop_dev&lt;/code&gt;, so stop your dev server first. If it complains that the source database is in use, that's why.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MySQL.&lt;/strong&gt; There's no template option, so dump and load:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"CREATE DATABASE shop_claude"&lt;/span&gt;
mysqldump shop_dev | mysql shop_claude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SQLite.&lt;/strong&gt; It's just a file. Copy it while nothing is writing to it, or use SQLite's own backup command, which is safe even if the file is open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sqlite3 ../shop/dev.db &lt;span class="s2"&gt;".backup dev.db"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then point each worktree at its own database in its &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: a separate .env per worktree
&lt;/h2&gt;

&lt;p&gt;Since worktrees don't get your ignored files, copy the &lt;code&gt;.env&lt;/code&gt; in and change the parts that must differ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ../shop/.env .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then edit it, for example in &lt;code&gt;shop-claude/.env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3001
&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgres://localhost:5432/shop_claude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep real secrets out of anything the agent might commit. Check that &lt;code&gt;.env&lt;/code&gt; is in &lt;code&gt;.gitignore&lt;/code&gt; in every worktree before you let an agent loose on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: tell each agent the rules
&lt;/h2&gt;

&lt;p&gt;Agents follow written instructions well. In each worktree, add a short note to &lt;code&gt;CLAUDE.md&lt;/code&gt; or &lt;code&gt;AGENTS.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Local dev&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Dev server: &lt;span class="sb"&gt;`PORT=3001 npm run dev`&lt;/span&gt; (use port 3001 only)
&lt;span class="p"&gt;-&lt;/span&gt; If a server is already running on 3001, reuse it. Don't start another.
&lt;span class="p"&gt;-&lt;/span&gt; Database: shop_claude (never shop_dev)
&lt;span class="p"&gt;-&lt;/span&gt; Stop any server you started when the task is done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This cuts down on duplicate servers more than anything else I've tried.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: clean up when an agent is done
&lt;/h2&gt;

&lt;p&gt;When the work is finished, you have three choices: merge it, keep it for later, or throw it away.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ../shop
git merge agent/claude-fix-cart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Throw it away (or clean up after merging):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git worktree remove ../shop-claude
git branch &lt;span class="nt"&gt;-D&lt;/span&gt; agent/claude-fix-cart   &lt;span class="c"&gt;# -D deletes even if unmerged&lt;/span&gt;
dropdb shop_claude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Check for leftover servers.&lt;/strong&gt; This lists everything listening on a TCP port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsof &lt;span class="nt"&gt;-nP&lt;/span&gt; &lt;span class="nt"&gt;-iTCP&lt;/span&gt; &lt;span class="nt"&gt;-sTCP&lt;/span&gt;:LISTEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for &lt;code&gt;node&lt;/code&gt;, &lt;code&gt;python&lt;/code&gt;, &lt;code&gt;php&lt;/code&gt; or &lt;code&gt;ruby&lt;/code&gt; processes on ports you weren't expecting. To see which folder one came from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-o&lt;/span&gt; pid,ppid,etime,command &lt;span class="nt"&gt;-p&lt;/span&gt; &amp;lt;pid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command line usually includes the project path, so you can tell whether it's from &lt;code&gt;shop-claude&lt;/code&gt; or &lt;code&gt;shop-codex&lt;/code&gt;. Stop it gently with &lt;code&gt;kill &amp;lt;pid&amp;gt;&lt;/code&gt;, and only use &lt;code&gt;kill -9 &amp;lt;pid&amp;gt;&lt;/code&gt; if it's still there a few seconds later.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same setup in Lokstack
&lt;/h2&gt;

&lt;p&gt;Disclosure: I build Lokstack, a Mac app, and this part is about my own app.&lt;/p&gt;

&lt;p&gt;The steps above work, but it's a lot of setup and cleanup for every task. Lokstack has a feature called lanes that does this per agent. Each AI agent (Claude Code, Cursor, Codex) gets its own lane: its own branch, its own port and its own database copy. When the agent is finished, a finish screen asks what should happen to the work: &lt;strong&gt;Add it to main&lt;/strong&gt;, &lt;strong&gt;Open a pull request&lt;/strong&gt;, &lt;strong&gt;Keep it for later&lt;/strong&gt; or &lt;strong&gt;Throw it away&lt;/strong&gt;. Your main branch and main database aren't touched until you choose.&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%2Fbekzyld4qsxp6bclupvf.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%2Fbekzyld4qsxp6bclupvf.png" alt="Lokstack lane finish screen: add it to main, keep it, or throw it away" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Agents screen also has a &lt;strong&gt;Left running&lt;/strong&gt; panel that lists the dev servers agents started and didn't stop, so you can stop them from there.&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%2Fx3ys4oy8dhrqkiec860b.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%2Fx3ys4oy8dhrqkiec860b.png" alt="Lokstack Agents screen with three lanes and the Left running panel" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A 43-second demo of lanes:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/mxLAjSPQjzs" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;To be upfront: lanes are a Pro feature and they're in beta. They work and have passed a full test pass, but details may change between releases. There's a 14-day free trial with no card. For launch, Pro is 50% off the first year ($39.99 instead of $79.99) with code LAUNCH50.&lt;/p&gt;

&lt;p&gt;If you'd rather do it by hand, everything in this post is plain git and shell, and it works fine. &lt;a href="https://lokstack.app" rel="noopener noreferrer"&gt;https://lokstack.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How many agents do you run on one project at once, and what breaks first for you? I'd like to hear it in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>git</category>
      <category>macos</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What's using port 3000 on my Mac? Find it, see who started it, and stop it safely</title>
      <dc:creator>Tj Thouhid</dc:creator>
      <pubDate>Sun, 18 Oct 2026 13:07:56 +0000</pubDate>
      <link>https://dev.to/tjthouhid/whats-using-port-3000-on-my-mac-find-it-see-who-started-it-and-stop-it-safely-5h0i</link>
      <guid>https://dev.to/tjthouhid/whats-using-port-3000-on-my-mac-find-it-see-who-started-it-and-stop-it-safely-5h0i</guid>
      <description>&lt;p&gt;You run &lt;code&gt;npm run dev&lt;/code&gt; and get this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: listen EADDRINUSE: address already in use :::3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The usual advice is "find the PID and kill it". That works, but it skips the questions that actually matter. &lt;em&gt;What&lt;/em&gt; is on port 3000? Which project does it belong to? Did I start it, did my editor, or did an AI agent start it in the background an hour ago? And is it safe to stop?&lt;/p&gt;

&lt;p&gt;Here's how to answer all of that on macOS with commands that are already installed. After that, I'll show how I do the same thing in a Mac app I build.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. A quick look
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsof &lt;span class="nt"&gt;-i&lt;/span&gt; :3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On macOS, plain &lt;code&gt;lsof -i :3000&lt;/code&gt; may print a service name such as &lt;code&gt;hbci&lt;/code&gt; instead of &lt;code&gt;3000&lt;/code&gt;; step 2 fixes that.&lt;/p&gt;

&lt;p&gt;This lists every process with a network connection on port 3000. That includes the server, but also your browser tabs that are connected to it, so the list can be longer than you expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Just the thing that's listening
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsof &lt;span class="nt"&gt;-nP&lt;/span&gt; &lt;span class="nt"&gt;-iTCP&lt;/span&gt;:3000 &lt;span class="nt"&gt;-sTCP&lt;/span&gt;:LISTEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-iTCP:3000&lt;/code&gt; limits it to TCP on port 3000.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-sTCP:LISTEN&lt;/code&gt; shows only the process that's &lt;em&gt;listening&lt;/em&gt;, which is the one holding the port.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-n&lt;/code&gt; and &lt;code&gt;-P&lt;/code&gt; skip name lookups. It's faster, and you see &lt;code&gt;3000&lt;/code&gt; rather than a service name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll get something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
node    48213 tj     23u  IPv6  0x...       0t0  TCP *:3000 (LISTEN)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might see two lines, one for IPv4 and one for IPv6. They can even be two different processes. That's how you get the confusing case where the browser shows an old version of your app while your terminal says the new one started fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. What is it, who owns it, and for how long?
&lt;/h2&gt;

&lt;p&gt;Take the PID and ask &lt;code&gt;ps&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-p&lt;/span&gt; 48213 &lt;span class="nt"&gt;-o&lt;/span&gt; pid,ppid,user,etime,command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  PID  PPID USER  ELAPSED COMMAND
48213 48190 tj   01:12:40 node /Users/tj/code/shop/node_modules/.bin/vite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;command&lt;/strong&gt; is the full command line. It often includes the project path (&lt;code&gt;/Users/tj/code/shop&lt;/code&gt; here), which is usually the quickest way to tell which project it belongs to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;etime&lt;/strong&gt; (shown as ELAPSED) is how long it's been running. An hour and twelve minutes means this isn't the server you just tried to start.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;user&lt;/strong&gt; is who owns it. If it isn't you, see step 4.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ppid&lt;/strong&gt; is the parent process. Run the same command on it to see what launched it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-p&lt;/span&gt; 48190 &lt;span class="nt"&gt;-o&lt;/span&gt; pid,ppid,user,etime,command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep going up and you'll usually hit &lt;code&gt;zsh&lt;/code&gt; and then Terminal, an editor's helper process (VS Code, for example), or an AI tool's shell. If the PPID is &lt;code&gt;1&lt;/code&gt;, the original parent has exited and macOS's &lt;code&gt;launchd&lt;/code&gt; adopted the process. That's typical for a server left running in the background after the thing that started it went away.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Nothing shows up? It may belong to another user
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;lsof&lt;/code&gt; only lists your own processes unless you run it with &lt;code&gt;sudo&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;lsof &lt;span class="nt"&gt;-nP&lt;/span&gt; &lt;span class="nt"&gt;-iTCP&lt;/span&gt;:3000 &lt;span class="nt"&gt;-sTCP&lt;/span&gt;:LISTEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the port is held by a process owned by &lt;code&gt;root&lt;/code&gt; or another user, this is how you'll see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Stop it, gently first
&lt;/h2&gt;



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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;kill&lt;/code&gt; sends a polite "please quit" signal (SIGTERM), so the program can shut down properly. Give it a couple of seconds and run the &lt;code&gt;lsof&lt;/code&gt; command from step 2 again. Only if it's still there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; 48213
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;kill -9&lt;/code&gt; ends it immediately, with no chance to clean up. Use it as the second step, not the first.&lt;/p&gt;

&lt;p&gt;A few things to watch for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Another user's process.&lt;/strong&gt; You'll get "Operation not permitted". You'd need &lt;code&gt;sudo kill 48213&lt;/code&gt;, so first be sure it's really something you mean to stop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Still busy after you stopped it?&lt;/strong&gt; Dev servers often start child processes. Run step 2 again and see what's listening now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It comes straight back?&lt;/strong&gt; Something is restarting it, such as a service manager, Docker, or an app like Laravel Herd. Stop it there instead of killing it again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ports 5000 and 7000.&lt;/strong&gt; On recent macOS versions, AirPlay Receiver listens on these. If a Flask app can't get port 5000, that's probably why. Pick another port, or turn AirPlay Receiver off in System Settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The same thing in Lokstack
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Disclosure: I build Lokstack, and this part is about my own app.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I built Lokstack partly because I got tired of running these commands one after another. It's a free Mac app, and everything in this section is on the free plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ports page.&lt;/strong&gt; Search for &lt;code&gt;3000&lt;/code&gt;. Lokstack shows which program holds the port, which project it belongs to, who started it, and how long it's been up. There are two buttons. &lt;strong&gt;Stop&lt;/strong&gt; asks the program to quit, like &lt;code&gt;kill&lt;/code&gt;. &lt;strong&gt;Force&lt;/strong&gt; stops it straight away, like &lt;code&gt;kill -9&lt;/code&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%2F3fcc1esgicl9rjcgism0.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%2F3fcc1esgicl9rjcgism0.png" alt="Lokstack Ports page: a listening port with the program, project, who started it, uptime, and Stop and Force buttons" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Why won't it start?" on a project's Overview.&lt;/strong&gt; If the project has a saved port and something else is using it, a red box says &lt;strong&gt;"Port 3000 is already taken"&lt;/strong&gt; with a &lt;strong&gt;Free port 3000&lt;/strong&gt; button. That's the one-click version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run &amp;amp; logs.&lt;/strong&gt; If the app you start prints &lt;code&gt;EADDRINUSE&lt;/code&gt; or "address already in use", Lokstack explains it in plain words and offers the same fix.&lt;/p&gt;

&lt;p&gt;What it won't do, so you know where the edges are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Databases and services are protected.&lt;/strong&gt; Lokstack won't stop them by accident.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Programs owned by another user&lt;/strong&gt; (for example a server running as root) can't be stopped from Lokstack. It says "Permission denied", and in Terminal you'd need &lt;code&gt;sudo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Laravel Herd sites&lt;/strong&gt; are stopped by asking Herd to stop all its services, not by killing that one process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Free port button only appears for projects with a saved port.&lt;/strong&gt; Stop and Force on the Ports page always work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;When you see &lt;code&gt;EADDRINUSE&lt;/code&gt;, find out what's actually listening, check what it is and who owns it, and stop it gently before you force it. If it keeps coming back, stop it where it's managed (Docker, a service manager, Herd) instead.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Lokstack is a free Mac app that shows what is using a port, which project it belongs to and who started it, and lets you stop it in one click. It won't touch your databases by accident. If you'd rather stay in Terminal, the commands above are all you need. &lt;a href="https://lokstack.app" rel="noopener noreferrer"&gt;https://lokstack.app&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What's the strangest thing you've found holding a port? I'd like to hear it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>macos</category>
      <category>webdev</category>
      <category>node</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
