{"id":168,"date":"2026-08-08T21:00:00","date_gmt":"2026-08-08T18:00:00","guid":{"rendered":"https:\/\/john-nessime.com\/blog\/?p=168"},"modified":"2026-08-04T14:55:23","modified_gmt":"2026-08-04T11:55:23","slug":"journald-vs-rsyslog-where-logs-live","status":"publish","type":"post","link":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/","title":{"rendered":"journald vs rsyslog: Where Your Linux Logs Actually Live"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The disk alert usually comes first. <code>\/var<\/code> sitting at 94 percent on a box that runs three services and logs almost nothing interesting. You go digging and find the same night&#8217;s SSH failures in two places: compressed binary files under <code>\/var\/log\/journal\/<\/code>, and plain text in <code>\/var\/log\/secure<\/code>. Same events. Two copies. Nobody decided that. It is just what the distro shipped.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The worse version of this problem is the mirror image. You reboot a server to clear something, come back to read what led up to it, and the journal starts at the reboot. Everything before is gone. Not rotated, not compressed, not archived somewhere clever. Gone, because the journal was living in RAM and nobody ever told it otherwise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Both of those are the same misunderstanding wearing different clothes: not knowing where your logs actually live. This post walks through the <strong>journald vs rsyslog<\/strong> split on a modern Linux server, what each one really stores, the three failure modes that bite in production, and how to decide which of the two is the copy you keep.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What actually happens when a process logs a line<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">On any systemd-based distribution, <code>systemd-journald<\/code> is the first stop for almost everything. It is not one option among several. It sits underneath.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Anything a unit writes to stdout or stderr, because systemd wires those to the journal by default.<\/li>\n\n<li>Kernel messages, read from the kernel ring buffer.<\/li>\n\n<li>Classic <code>syslog(3)<\/code> calls from libc, which land on the <code>\/dev\/log<\/code> socket that journald owns.<\/li>\n\n<li>Native journal API calls from anything linked against libsystemd, which carry structured key-value fields instead of a flat string.<\/li>\n\n<li>Audit records, if <code>Audit=yes<\/code> is in effect.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">journald writes all of that into indexed binary journal files. Then, on most server distributions, rsyslog gets a <em>second copy<\/em> of the same events and writes them out as text into <code>\/var\/log\/messages<\/code>, <code>\/var\/log\/secure<\/code>, <code>\/var\/log\/maillog<\/code> and friends.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That handoff happens one of two ways, and which one your box uses matters more than most people expect. More on that below. First, the part that costs you an outage.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Before changing anything, look at the effective journald configuration rather than the file you think is authoritative. Distributions ship drop-ins under <code>\/usr\/lib\/systemd\/journald.conf.d\/<\/code> that quietly override upstream defaults:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Print the merged configuration, including every drop-in, in load order\nsystemd-analyze cat-config systemd\/journald.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is the single most useful command in this whole post. Half the arguments about &#8220;what the default is&#8221; evaporate once you run it, because upstream systemd and your distribution frequently disagree about <code>ForwardToSyslog<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Failure one: the journal that was never on disk<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">journald&#8217;s <code>Storage=<\/code> setting defaults to <code>auto<\/code>. That word does more work than it looks like. Under <code>auto<\/code>, journald writes to <code>\/var\/log\/journal\/<\/code> <em>only if that directory already exists<\/em>. If it does not, journald falls back to <code>\/run\/log\/journal\/<\/code>, which is tmpfs. Memory. Wiped on reboot.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nothing warns you. <code>journalctl<\/code> works fine, colours are pretty, filters work. You just silently have no history.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The quickest test is boot history. If the journal is persistent you see multiple boots; if it is volatile you see exactly one:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>journalctl --list-boots<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To make it persistent, create the directory, let systemd-tmpfiles apply the correct ownership and ACLs, then restart the daemon and flush anything still held in RAM:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir -p \/var\/log\/journal\nsudo systemd-tmpfiles --create --prefix \/var\/log\/journal\nsudo systemctl restart systemd-journald\nsudo journalctl --flush\njournalctl --list-boots<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>systemd-tmpfiles<\/code> step is the one people skip. The journal directory needs specific group ownership and ACLs so that unprivileged users can read their own entries and members of the <code>systemd-journal<\/code> group can read everything. Creating the directory with a bare <code>mkdir<\/code> and walking away usually works, but it is the kind of &#8220;usually&#8221; that produces a confusing permissions ticket six months later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want the behaviour to be explicit rather than inferred from a directory&#8217;s existence, set it in <code>\/etc\/systemd\/journald.conf.d\/00-storage.conf<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[Journal]\nStorage=persistent<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A drop-in file is better than editing the main config, because package upgrades will not fight you over it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Failure two: paying for the same log line twice<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once the journal is persistent, you are storing everything twice on a default server build: once as compressed binary in the journal, once as text under <code>\/var\/log\/<\/code>. Two stores, two completely separate retention policies, neither of which knows the other exists.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The journal is capped by <code>SystemMaxUse=<\/code> and <code>SystemKeepFree=<\/code>. Left unset, they default to 10 percent and 15 percent of the filesystem respectively, and journald honours whichever is stricter. Recent systemd also caps those calculated defaults so they do not grow without bound on a large disk, which is worth knowing if you have ever wondered why a huge volume did not produce a proportionally huge journal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The text copy is capped by <code>logrotate<\/code>, configured somewhere completely different, usually <code>\/etc\/logrotate.d\/rsyslog<\/code>, on a weekly or daily schedule with its own <code>rotate<\/code> count.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Measure both before you tune either:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># What the journal is actually consuming on disk\njournalctl --disk-usage\n\n# What everything under \/var\/log costs, sorted, biggest last\nsudo du -sh \/var\/log\/* | sort -h<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On a small VPS this stops being academic quickly. A modest instance from a provider like InterServer, Hetzner or DigitalOcean often has <code>\/var<\/code> sharing a single root volume of 20 to 40 GB. A journal allowed to take 10 percent of that, plus four weeks of rotated text logs, plus a database, plus a container image cache, is how you end up paged at two in the morning for something that is not a real incident.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you decide the text files are the copy you keep, put the journal on a short leash:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[Journal]\n# Hard ceiling on total journal size\nSystemMaxUse=200M\n# Never let the journal push free space below this\nSystemKeepFree=1G\n# Discard entries older than this regardless of size\nMaxRetentionSec=2day<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Those three do different jobs and you generally want at least two of them. <code>SystemMaxUse<\/code> bounds the journal itself. <code>SystemKeepFree<\/code> protects the rest of the filesystem from the journal. <code>MaxRetentionSec<\/code> bounds it in time, which is what auditors and data-retention policies actually care about.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To reclaim space immediately without waiting for the next rotation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Trim archived journal files until the total falls below 500M\nsudo journalctl --vacuum-size=500M\n\n# Or trim by age instead\nsudo journalctl --vacuum-time=7d<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">One caveat that surprises people: vacuuming only removes <em>archived<\/em> journal files. The currently active file is never deleted. If almost all your usage is in one large active file, run <code>journalctl --rotate<\/code> first, then vacuum.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Failure three: two rate limiters, both silent<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the one that is invisible until it matters, and it is the real reason to understand the journald vs rsyslog relationship rather than treating them as interchangeable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are <em>two independent rate limiters<\/em> in the default pipeline, and both drop messages quietly.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">journald&#8217;s limiter<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">journald applies <code>RateLimitIntervalSec=<\/code> and <code>RateLimitBurst=<\/code> per service, defaulting to 30 seconds and 10000 messages. Exceed the burst inside the interval and the rest of that service&#8217;s messages in that window are discarded. Not queued. Discarded.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The one piece of good news is that journald tells you, in the journal itself. Grep for it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>journalctl --grep=\"Suppressed\" -n 50 --no-pager<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A chatty web server or a container using the journald log driver will hit this. Rather than disabling rate limiting globally, override it for the one unit that needs it, using a drop-in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \/etc\/systemd\/system\/nginx.service.d\/logging.conf\n[Service]\nLogRateLimitIntervalSec=30s\nLogRateLimitBurst=50000<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Per-unit values override <code>journald.conf<\/code> for that unit only, which is exactly what you want. Turning the global limiter off means one runaway process can fill your disk and take the box down. Turning it up for the single service you know is noisy is a bounded decision.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">rsyslog&#8217;s limiter<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If rsyslog is reading via the <code>imjournal<\/code> module, it applies <em>its own<\/em> rate limit on top, defaulting to 20000 messages per 600 seconds. A message can therefore survive journald&#8217;s limiter, land in the journal, and still never reach <code>\/var\/log\/messages<\/code> or your remote log host.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is the nasty case, because your local investigation finds the events but your centralised alerting never fired. Two people look at two sources and reach opposite conclusions about whether something happened.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">rsyslog exposes counters for this through its statistics module, including how many messages it read from the journal, how many it submitted onward, and how many it discarded to rate limiting. Enable <code>impstat<\/code> if you run anything log-volume-sensitive; the discard counter is the number that tells you whether your pipeline is lying to you.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How rsyslog gets its copy: imjournal or imuxsock<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">There are two mechanisms, they behave differently under load, and running both at once is a classic source of duplicate lines.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">imuxsock: journald pushes a copy to a socket<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">With <code>ForwardToSyslog=yes<\/code> in journald, journald writes a classic syslog-formatted copy of each message to a dedicated socket, and rsyslog reads it with <code>imuxsock<\/code>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Where it wins:<\/strong> simple, no state file, no second rate limiter, and no possibility of rsyslog reading back its own output and looping.<\/li>\n\n<li><strong>Where it does not:<\/strong> you get the flat syslog view only. Structured journal fields such as the originating unit are not carried across.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">imjournal: rsyslog pulls from the journal<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>imjournal<\/code> reads journal files directly and keeps a state file so it can resume where it left off after a restart.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Where it wins:<\/strong> structured fields survive the trip. If you want to route or template on the systemd unit name rather than parsing it out of a message string, this is the only option of the two.<\/li>\n\n<li><strong>Where it does not:<\/strong> extra rate limiter to reason about, a state file that can drift, and a documented risk that a corrupted journal database causes rsyslog to re-read the same entries in a loop. rsyslog&#8217;s own documentation recommends using <code>imuxsock<\/code> instead unless you specifically need the structured data.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">A representative <code>imjournal<\/code> load line, with the rate limit stated explicitly rather than left implicit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module(load=\"imjournal\"\n       StateFile=\"imjournal.state\"\n       Ratelimit.Interval=\"600\"\n       Ratelimit.Burst=\"20000\")<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Writing the defaults out by hand is worth the two extra lines. The next person to debug missing messages will see the limiter exists instead of assuming there isn&#8217;t one.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To find out which mechanism your box is using right now:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>grep -R \"imjournal|imuxsock\" \/etc\/rsyslog.conf \/etc\/rsyslog.d\/ 2&gt;\/dev\/null\ngrep -R \"ForwardToSyslog\" \/etc\/systemd\/journald.conf \/etc\/systemd\/journald.conf.d\/ \/usr\/lib\/systemd\/journald.conf.d\/ 2&gt;\/dev\/null<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the first command returns both modules and the second returns <code>ForwardToSyslog=yes<\/code>, you have a duplication problem. Pick one path and disable the other.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Only one of the two leaves the box<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the argument that settles most journald vs rsyslog debates in practice. journald is a local store. In a stock server install it has no mechanism for shipping logs to another host. There are separate systemd components for journal upload and reception, and third-party projects that read the journal and forward it, but none of that is in the default path.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">rsyslog forwards as a first-class feature, and it does the part that actually matters: it buffers when the destination is unreachable.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>global(workDirectory=\"\/var\/spool\/rsyslog\")\n\naction(type=\"omfwd\"\n       target=\"logs.example.net\"\n       port=\"514\"\n       protocol=\"tcp\"\n       action.resumeRetryCount=\"-1\"\n       queue.type=\"LinkedList\"\n       queue.filename=\"fwd_loghost\"\n       queue.maxDiskSpace=\"1g\"\n       queue.saveOnShutdown=\"on\")<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Line by line, because these are not decoration:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>workDirectory<\/code> is where spool files get written. Without it, the disk queue has nowhere to go.<\/li>\n\n<li><code>protocol=\"tcp\"<\/code> rather than UDP. UDP syslog silently drops under congestion, which defeats the point of forwarding at all.<\/li>\n\n<li><code>queue.type=\"LinkedList\"<\/code> makes the action asynchronous so a slow destination does not block local processing.<\/li>\n\n<li><code>queue.filename<\/code> is what actually enables disk assistance. In-memory queue first, spilling to disk when it fills. The name must be unique across every action in the config.<\/li>\n\n<li><code>queue.maxDiskSpace<\/code> caps that spool. Set it, or a long outage at the far end fills the disk you were trying to protect.<\/li>\n\n<li><code>queue.saveOnShutdown=\"on\"<\/code> persists whatever is still queued across a service restart.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">One honest caveat on <code>action.resumeRetryCount=\"-1\"<\/code>. Infinite retry is the right default for &#8220;never lose a log line&#8221;, but there are reported cases where a relay under sustained back-pressure stops accepting new inbound messages while retrying forever. If your host is a relay rather than a leaf, test that behaviour deliberately with the destination firewalled off before you trust it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">rsyslog is not the only way off the box. Grafana Alloy into Loki, Vector, and Fluent Bit all read the journal directly and speak modern backends, and hosted platforms such as Better Stack, Papertrail or Datadog will take a plain syslog stream if you would rather not run the storage side. The mechanism differs; the decision does not. Something has to own the write path off the machine, and journald on its own is not it.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">journald vs rsyslog: how I would decide<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Stop asking which is better. Ask which one is the copy you are willing to be judged on, then make the other one cheap.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Do logs need to leave this machine?<\/strong> If yes, rsyslog or a dedicated shipper owns the outbound path. That is settled before anything else.<\/li>\n\n<li><strong>Do you troubleshoot mostly by unit?<\/strong> If <code>journalctl -u something -b<\/code> is your muscle memory, journald is your primary read path and should get the retention budget.<\/li>\n\n<li><strong>Do existing tools read text files?<\/strong> Fail2ban, logwatch, older SIEM collectors and a lot of home-grown scripts parse <code>\/var\/log\/*<\/code>. Turning rsyslog off breaks them quietly.<\/li>\n\n<li><strong>How much disk do you actually have?<\/strong> Under about 40 GB, keeping two full copies is an unforced error. Cap one hard.<\/li>\n\n<li><strong>Is tamper-evidence a requirement?<\/strong> journald supports Forward Secure Sealing, which detects after-the-fact modification of journal files. Shipping to an append-only remote store is the more commonly accepted answer, and the two are not mutually exclusive.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">The configuration I reach for first on a general-purpose server: journald persistent with a hard cap for a few days of fast local querying, rsyslog kept for the syslog files that other tools expect plus reliable forwarding off-box, <code>imuxsock<\/code> as the handoff unless something genuinely needs structured fields, and logrotate retention trimmed down because the remote copy is the one that matters for anything older than a week.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Journal only shows the current boot.<\/strong> Volatile storage. <code>journalctl --list-boots<\/code> confirms it, and the fix is the persistent-storage sequence above.<\/li>\n\n<li><strong>Events in journalctl but not in \/var\/log\/messages.<\/strong> Either rsyslog is not reading from the journal at all, or the <code>imjournal<\/code> rate limiter is discarding. Check which input module is loaded first.<\/li>\n\n<li><strong>Every line appears twice in the text logs.<\/strong> Both <code>imjournal<\/code> and <code>imuxsock<\/code> are active while <code>ForwardToSyslog=yes<\/code>. Disable one path.<\/li>\n\n<li><strong>Bursts of messages disappear during incidents.<\/strong> That is a rate limiter, and incidents are exactly when services get loud. Search for suppression notices and raise the limit for that specific unit.<\/li>\n\n<li><strong>journalctl reports corruption or behaves oddly.<\/strong> Run <code>journalctl --verify<\/code>. If files are damaged, <code>journalctl --rotate<\/code> starts a fresh active file so new writes are clean, then vacuum the bad archives.<\/li>\n\n<li><strong>&#8220;Journal has been rotated since unit was started.&#8221;<\/strong> Not an error. Rotation happened mid-session, so <code>journalctl -u<\/code> cannot map the full range. Re-run the query without the unit filter or widen the time range.<\/li>\n\n<li><strong>Disk still full after vacuuming.<\/strong> Vacuum skips the active journal file. Rotate first, then vacuum again.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Common mistakes<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Assuming the journal is persistent because <code>journalctl<\/code> returns results. It always returns results. The question is how far back.<\/li>\n\n<li>Disabling rsyslog on a box where fail2ban, logwatch or a scraper still reads <code>\/var\/log\/secure<\/code>. Nothing errors. Detection just stops.<\/li>\n\n<li>Setting <code>RateLimitBurst=0<\/code> globally to &#8220;stop losing logs&#8221;, then having a crash-looping service fill the disk in an afternoon.<\/li>\n\n<li>Editing <code>\/etc\/systemd\/journald.conf<\/code> directly and being surprised when a vendor drop-in overrides it. Use a drop-in of your own with a name that sorts later.<\/li>\n\n<li>Forwarding over UDP because it is the one-line version. It drops silently under exactly the load that produced the logs you wanted.<\/li>\n\n<li>Enabling a disk-assisted queue without <code>queue.maxDiskSpace<\/code>, turning a remote outage into a local disk-full outage.<\/li>\n\n<li>Tuning journald limits on a machine whose real problem is that one application logs every health check at info level. Fix the source first.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Best practices<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Make storage explicit. <code>Storage=persistent<\/code> or <code>Storage=volatile<\/code>, never left to <code>auto<\/code> on a server you care about.<\/li>\n\n<li>Always set <code>SystemKeepFree<\/code> alongside <code>SystemMaxUse<\/code>. The first bounds the journal, the second protects everything else on the volume from it.<\/li>\n\n<li>Decide consciously which store is authoritative, and write it in the runbook. Two stores with no stated owner means neither gets maintained.<\/li>\n\n<li>Use exactly one journal-to-rsyslog path. Both is duplication; neither is silent data loss.<\/li>\n\n<li>Override rate limits per unit, not globally.<\/li>\n\n<li>Monitor <code>journalctl --disk-usage<\/code> as a metric, not as something you check after the alert.<\/li>\n\n<li>Ship off-box with TCP and a bounded disk-assisted queue, and test it with the destination firewalled off before you rely on it.<\/li>\n\n<li>Keep the local copy short and the remote copy long. Local disk is the expensive place to store history.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Frequently asked questions<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Can I just disable rsyslog and use journald only?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">On a self-contained box with no remote logging and nothing parsing text files, yes, and it saves real disk. Before you do it, grep your configuration management and cron jobs for <code>\/var\/log\/<\/code> paths, and check whether fail2ban or any monitoring agent reads those files. That is where this bites people.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Can I disable journald and use rsyslog only?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Not meaningfully. journald is how systemd captures unit stdout and stderr, so it stays in the path regardless. What you can do is set <code>Storage=volatile<\/code> with a small <code>RuntimeMaxUse<\/code> so it holds a short in-memory window and rsyslog owns everything durable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Where are journald logs stored?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>\/var\/log\/journal\/<\/code> when persistent, <code>\/run\/log\/journal\/<\/code> when volatile. They are indexed binary files, not text, so <code>grep<\/code> and <code>tail<\/code> do not work on them directly. Use <code>journalctl<\/code>, or <code>journalctl -o json<\/code> if you want to pipe structured output into something else.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Why does journalctl show entries that never reached \/var\/log\/messages?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Three usual causes: rsyslog is not reading the journal at all, the <code>imjournal<\/code> rate limiter dropped them, or a severity filter such as <code>MaxLevelSyslog<\/code> or an rsyslog rule excluded that facility or priority. Check in that order.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Is the binary journal format a problem for log analysis?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Locally, no. Structured fields and fast filtering are genuinely better than parsing text with regex. It becomes a problem when you need to move logs somewhere else, because almost every collector expects text or JSON. That conversion step is precisely the role rsyslog or a modern shipper plays.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How much disk should the journal be allowed to use?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Work backwards from how far back you actually query locally. If you rarely look past yesterday, a few hundred megabytes with <code>MaxRetentionSec<\/code> set to two or three days is plenty. Anything older belongs in a remote store where it is cheaper and survives the machine.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Does journald compress logs automatically?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes. <code>Compress=<\/code> defaults to enabled and applies to entries above a size threshold, which is one reason the journal is often smaller than the equivalent text files despite carrying more metadata. It does not remove the need for a size cap.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The one thing worth remembering<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The journald vs rsyslog question is not a contest. On a stock server both are running, both are storing the same events, and the defaults were chosen by your distribution rather than by you. The failure modes all come from that: a journal in RAM that vanishes on reboot, two uncoordinated retention policies eating the same disk, and two rate limiters dropping messages without anyone noticing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Run <code>systemd-analyze cat-config systemd\/journald.conf<\/code> and <code>journalctl --list-boots<\/code> on your servers. Two commands, thirty seconds, and you will know whether the logs you would reach for during an incident are actually there.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Need help sorting out your logging pipeline?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Logging is one of those areas where the defaults work well enough to hide the problem until an incident makes it expensive. If any of the above sounded familiar, these are the things I take on:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Auditing journald and rsyslog on existing servers and telling you exactly where each log line lives, how long it survives, and what is being silently dropped.<\/li>\n\n<li>Fixing volatile journals, runaway <code>\/var<\/code> growth and duplicate text-and-binary storage on small VPS instances.<\/li>\n\n<li>Setting up reliable off-box forwarding with disk-assisted queues, TCP or RELP transport, and TLS where it is required.<\/li>\n\n<li>Migrating from text-file scraping to a structured pipeline into Loki, Elasticsearch or a hosted log platform, without losing the alerts you already depend on.<\/li>\n\n<li>Tuning rate limits and retention per service so noisy applications stop hiding the messages that matter.<\/li>\n\n<li>Writing the runbook that says which store is authoritative, so the next engineer does not have to reverse-engineer it during an outage.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Send me your <code>journald.conf<\/code>, your <code>rsyslog.conf<\/code>, or the output of <code>journalctl --disk-usage<\/code> and I will tell you what I see before we talk about scope.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/www.upwork.com\/freelancers\/~01f15a912ad84a6620\" target=\"_blank\" rel=\"noreferrer noopener\">Work with me on Upwork<\/a><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>On a stock Linux server, journald and rsyslog are both running and both storing the same events, with retention policies that don&#8217;t know about each other. Here&#8217;s where each log line actually lives, the three failure modes that bite in production, and how to decide which copy you keep.<\/p>\n","protected":false},"author":1,"featured_media":169,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,26,63],"tags":[105,255,253,6,257,116,14,96,10,254,72,256,97,4,138],"class_list":["post-168","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-linux","category-system-administration","tag-disk-space","tag-journalctl","tag-journald","tag-linux","tag-log-retention","tag-logging","tag-logs","tag-observability","tag-production","tag-rsyslog","tag-sysadmin","tag-syslog","tag-systemd","tag-troubleshooting","tag-vps","entry","has-media"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>journald vs rsyslog: Where Your Logs Live<\/title>\n<meta name=\"description\" content=\"journald vs rsyslog explained: why Linux servers store logs twice, why the journal vanishes on reboot, and which copy you should actually keep.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"journald vs rsyslog: Where Your Logs Live\" \/>\n<meta property=\"og:description\" content=\"journald vs rsyslog explained: why Linux servers store logs twice, why the journal vanishes on reboot, and which copy you should actually keep.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/\" \/>\n<meta property=\"og:site_name\" content=\"John Nessime\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-08T18:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/journald-vs-rsyslog-where-logs-live.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"627\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"John Nessime\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"John Nessime\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/\"},\"author\":{\"name\":\"John Nessime\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\"},\"headline\":\"journald vs rsyslog: Where Your Linux Logs Actually Live\",\"datePublished\":\"2026-08-08T18:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/\"},\"wordCount\":3159,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\"},\"image\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/journald-vs-rsyslog-where-logs-live.png\",\"keywords\":[\"Disk Space\",\"journalctl\",\"journald\",\"Linux\",\"Log Retention\",\"Logging\",\"Logs\",\"Observability\",\"Production\",\"rsyslog\",\"Sysadmin\",\"Syslog\",\"Systemd\",\"Troubleshooting\",\"VPS\"],\"articleSection\":[\"DevOps\",\"Linux\",\"System Administration\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/\",\"name\":\"journald vs rsyslog: Where Your Logs Live\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/journald-vs-rsyslog-where-logs-live.png\",\"datePublished\":\"2026-08-08T18:00:00+00:00\",\"description\":\"journald vs rsyslog explained: why Linux servers store logs twice, why the journal vanishes on reboot, and which copy you should actually keep.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/#primaryimage\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/journald-vs-rsyslog-where-logs-live.png\",\"contentUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/journald-vs-rsyslog-where-logs-live.png\",\"width\":1200,\"height\":627,\"caption\":\"Diagram showing systemd-journald as the first stop for all Linux log sources, then branching into two stored copies: binary journal files under \\\/var\\\/log\\\/journal capped by SystemMaxUse, and a handoff through imuxsock or imjournal into rsyslog, which writes text files and forwards over TCP to a remote log host.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/journald-vs-rsyslog-where-logs-live\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"journald vs rsyslog: Where Your Linux Logs Actually Live\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/\",\"name\":\"John Nessime\",\"description\":\"Cloud, DevOps, Data &amp; AI \u2014 Built, Tested, Explained\",\"publisher\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\",\"name\":\"John Nessime\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\",\"contentUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\",\"width\":512,\"height\":512,\"caption\":\"John Nessime\"},\"logo\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\"},\"description\":\"AWS Certified Solutions Architect helping businesses build reliable cloud, data, reporting, and automation solutions. I help startups, agencies, and growing businesses replace manual processes and disconnected data with practical AWS architectures, clean data pipelines, useful dashboards, and maintainable automation.\",\"sameAs\":[\"https:\\\/\\\/john-nessime.com\\\/blog\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/john-m-nessime\"],\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/author\\\/johnnessime\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"journald vs rsyslog: Where Your Logs Live","description":"journald vs rsyslog explained: why Linux servers store logs twice, why the journal vanishes on reboot, and which copy you should actually keep.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/","og_locale":"en_US","og_type":"article","og_title":"journald vs rsyslog: Where Your Logs Live","og_description":"journald vs rsyslog explained: why Linux servers store logs twice, why the journal vanishes on reboot, and which copy you should actually keep.","og_url":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/","og_site_name":"John Nessime","article_published_time":"2026-08-08T18:00:00+00:00","og_image":[{"width":1200,"height":627,"url":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/journald-vs-rsyslog-where-logs-live.png","type":"image\/png"}],"author":"John Nessime","twitter_card":"summary_large_image","twitter_misc":{"Written by":"John Nessime","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/#article","isPartOf":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/"},"author":{"name":"John Nessime","@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105"},"headline":"journald vs rsyslog: Where Your Linux Logs Actually Live","datePublished":"2026-08-08T18:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/"},"wordCount":3159,"commentCount":0,"publisher":{"@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105"},"image":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/#primaryimage"},"thumbnailUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/journald-vs-rsyslog-where-logs-live.png","keywords":["Disk Space","journalctl","journald","Linux","Log Retention","Logging","Logs","Observability","Production","rsyslog","Sysadmin","Syslog","Systemd","Troubleshooting","VPS"],"articleSection":["DevOps","Linux","System Administration"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/","url":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/","name":"journald vs rsyslog: Where Your Logs Live","isPartOf":{"@id":"https:\/\/john-nessime.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/#primaryimage"},"image":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/#primaryimage"},"thumbnailUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/journald-vs-rsyslog-where-logs-live.png","datePublished":"2026-08-08T18:00:00+00:00","description":"journald vs rsyslog explained: why Linux servers store logs twice, why the journal vanishes on reboot, and which copy you should actually keep.","breadcrumb":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/#primaryimage","url":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/journald-vs-rsyslog-where-logs-live.png","contentUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/journald-vs-rsyslog-where-logs-live.png","width":1200,"height":627,"caption":"Diagram showing systemd-journald as the first stop for all Linux log sources, then branching into two stored copies: binary journal files under \/var\/log\/journal capped by SystemMaxUse, and a handoff through imuxsock or imjournal into rsyslog, which writes text files and forwards over TCP to a remote log host."},{"@type":"BreadcrumbList","@id":"https:\/\/john-nessime.com\/blog\/devops\/journald-vs-rsyslog-where-logs-live\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/john-nessime.com\/blog\/"},{"@type":"ListItem","position":2,"name":"journald vs rsyslog: Where Your Linux Logs Actually Live"}]},{"@type":"WebSite","@id":"https:\/\/john-nessime.com\/blog\/#website","url":"https:\/\/john-nessime.com\/blog\/","name":"John Nessime","description":"Cloud, DevOps, Data &amp; AI \u2014 Built, Tested, Explained","publisher":{"@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/john-nessime.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105","name":"John Nessime","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png","url":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png","contentUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png","width":512,"height":512,"caption":"John Nessime"},"logo":{"@id":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png"},"description":"AWS Certified Solutions Architect helping businesses build reliable cloud, data, reporting, and automation solutions. I help startups, agencies, and growing businesses replace manual processes and disconnected data with practical AWS architectures, clean data pipelines, useful dashboards, and maintainable automation.","sameAs":["https:\/\/john-nessime.com\/blog","https:\/\/www.linkedin.com\/in\/john-m-nessime"],"url":"https:\/\/john-nessime.com\/blog\/author\/johnnessime\/"}]}},"_links":{"self":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts\/168","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/comments?post=168"}],"version-history":[{"count":1,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts\/168\/revisions"}],"predecessor-version":[{"id":170,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts\/168\/revisions\/170"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/media\/169"}],"wp:attachment":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/media?parent=168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/categories?post=168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/tags?post=168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}