Hacker Newsnew | past | comments | ask | show | jobs | submit | linsomniac's commentslogin

I also just recently enabled zswap on my NixOS setup, it's been working fine. I have 32GB of RAM and 64GB of swap, so I really don't need it, but it hasn't hurt.

I was expecting some problems with my switch to NixOS back in June, but it's been just superb. Even things like building deb packages for my Ubuntu 26.04 machines at work have not been a problem at all.

I had dabbled with NixOS for a year or two before making the switch and had some familiarity with the nixlang and various concepts (SOPS, age, flakes). But, what really smoothed out the switch was using Claude Code to develop the NixOS configs. Everything is easy to do that way, and any issues are easy to back out.


Claude code/Git/NixOS is such a nice system to work with.

You can build your entire system from a worktree and merge if it works or boot the old generation if it doesn't. This is great for trialing new kernels, NixOS releases, or alternate Window managers, and rolling back is trivial.

One downside is that there is only one stable NixOS at a time, and no LTS. However in practice I haven't found this to be an issue across multiple desktops, servers and SBCs.


Agreed. One additional thing I do is I have the same setup on my main work workstation and also my old work laptop, so when I do a big swath of package updates (about once a month) I do it on my "scratch monkey" first and make sure nothing obvious breaks. I started doing this after a GNOME update broke my GDM (as you say, until I booted the old generation, but still was a work interruption).

I'm using NixOS "latest" on my workstation, for no particularly good reason.

One success I had was with building up a custom vim setup. I had previously been using Lunar and Astro as an opionated vim distro with LSP+Treesitter and some other "table stakes" things a modern editor should have. But there wasn't a clear way to install Astro in NixOS when I tried it manually. So I just told Claude Code what plugins and settings I wanted in neovim, and now I have a single file that fully describes my vim setup. Before with Astro and Lunar the configs were spread out all over a bunch of files.

I was also able to get Claude Code to bundle up gitbutler-cli, which I wanted to try but so far have not. It builds it from source because there was no existing derivation. It takes a stunningly long time to build, but otherwise it has worked very well in my simple testing of it. Plus, I can build on my powerful laptop and then use that to seed my old, slow ThinkPad T470s and even slower chromebook that I also put my config on.


>I don't see how anyone can be using Claude with prices like this

One potential deciding point is that Claude still has a $200/mo 20x plan, where, since Sept 11, OpenAI does not and has no ETA for the return.

I downgraded my OpenAI plan 2 months ago to the $100/mo, but my usage has gone way up, but now I can no longer upgrade to the $200/mo plan ("This option is temporarily unavailable"). Thankfully I have 2 usage resets available, but I'll probably be switching back to Claude; I was super happy with Astra but I'm burning through tokens and have 4 days before my next reset.


I've been toying with a similar idea for ~6 months: A lightweight job status dashboard.

I wanted something that required no setup, but could just push success/failure messages to as part of various cron jobs, windows tasks, and shell scripts we run throughout our organization.

StatShed server: https://github.com/statshed/statshed-server StatShed go-cli: https://github.com/statshed/statshed-gocli

The idea is kind of like "ntfy.sh", but for jobs status. You can send a "started" message at the beginning, update a "status" message periodically throughout the job, then send a "failed" message (optionally with logs) or a "success". Then a web dashboard gives you an overview with ability to drill down.

We use Icinga for monitoring and paging, but this just gives an overview for a quick look at things we don't want heavy duty monitoring on. Like my laptop backups, information about ansible runs across our fleet, etc.


Beware that rust coreutils on 26.04 currently has really bad performance with larger block sizes. Ganeti uses "dd bs=1M" as part of a disc image transfer pipeline, and with 26.04 performance dropped from ~350MB/sec to 30MB/sec, with the dd command CPU-bounded.

The issue seems to be that it is operating on partial buffers and then having to copy remainder of that 1M buffer around as part is consumed. Coreutils 0.11 solves that but 26.04 is at v0.8.

I've always used "bs=32k" because decades ago I did some testing and found that seemed to be large enough that it reduced the overhead while not being so large that it caused other problems, one of the most noticeable being scheduler issues where performance went into the toilet, especially on SD or USB thumb drives. Using this also seems to work better with rust coreutils dd.


How can a command which was explicitly designed to do nothing but read and write disk become CPU bound?

That's is famously not what 'dd' was designed to do. Its description in the original Unix 6th Edition manual was 'convert and copy a file'. It's infamous for people mis-remembering it as a disc copier when it was actually a file transcoding utility that understood EBCDIC and could re-block things.

I think we are saying the same thing. By disk, i meant disk I/O which is the main practical purpose of the tool. Of course, Linux being Unix, a raw disk is a file, so is /dev/null.

Of course a file can be everything, which is a kind of the point of Linux. But that doesn't change the fact that 'dd' is for disk (or file) I/O. Also please don't argue semantics, it leads nowhere.

But that's not the main point. The main point is the Rust coreutils version of dd is slow. I highly doubt it's impossible to write an implementation in Rust that's as fast as the C one. But the Rust community needs to invest time and energy into finding why that's the case and fixing it. Until that happens the broader Linux community is right to push back on adopting it.


>But the Rust community needs to invest time and energy into finding why that's the case and fixing it.

As I said in my post, the rust coreutils team HAS fixed this in 0.11. It's just that Ubuntu 26.04 is stuck on the older one.

Shipping a coreutils that is version 0.8 in an LTS release seems like an interesting choice.


Sorry I didn't see your post.

But I guess that shows another weakness of Ubuntu's model of versioning. You can't fix a bug if they don't merge. They have their own bugtracker (and so does every distro?) so you, Mr Dev have to deal with angry users not only on your Github Issues page, but on every distro's own bugtracker as well, and will have to perpetually support whatever old version they decided to shit (times X distro).

Does that mean BTW that they'll keep shipping the same broken dd for the next 2(4) years?


Why are we still using dd?

Seriously, it's a weird obtuse command. Weird syntax that doesn't match anything else, and the block size shouldn't be needed 99% of the time. A modern tool should figure out a good value on its own, either by interrogating the devices at both ends, or by benchmarking, or both.


The 'wierd syntax' has finally been getopt-ified. On the C GNU coreutils 'dd', and in a couple of the BSDs 'dd's.

* https://jdebp.uk/Softwares/dd-with-getopt.html

It only took 52 years. My prediction stands, by the way. (-:


I don’t know of a better tool that operates on raw blocks, maybe there is one.

`dd` is a real power user command, I’d prefer that it isn’t doing “intelligent” things, especially not by default.


How about bmaptool? It can work on sparse images.

In general, I don't see the point in manually specifying block sizes most of the time. What I want nearly always the maximum performance, and that should be possible to derive from the hardware, and/or benchmarking.

What about uses like say, skipping data? seek= and skip= are in block sizes, that may not be ideal for performance.

A smart tool should be able to write in 1 MB blocks and yet still skip 512 bytes.


    cp file.iso /dev/sda

This isn't portable though, it's a GNU-specific "smart" things. Elsewhere, this overwrites the target device file.

Redirection doesn't overwrite device files, so

  cat foo.img > /dev/sda
works and should be portable. No control over the buffer size, though.

And no printing of progress either.

How exactly is cp not portable?

Whatever behaviour you’re describing is not how POSIX mandates cp to work. In fact you can do this with busybox too.

cp will open("/dev/sda", O_WRONLY | O_TRUNC) and simply start writing to that file descriptor.


this works great but in my experience sometimes you should add

  && sync
not sure why it's necessary only sometimes!

The kernel has a cache used for block devices.

If you want to be more targeted:

    blockdev --flushbufs /dev/sda

ProTip: You can switch back to Gnu coreutils on 26.04 with:

apt install coreutils-from-gnu coreutils-from-uutils- --allow-remove-essential

And pin it so an upgrade doesn't flip it back with:

printf 'Package: coreutils-from-uutils\nPin: release a=*\nPin-Priority: -10\n' \ | sudo tee /etc/apt/preferences.d/uutils > /dev/null


Just curious, why the 'sudo tee {file} > /dev/null'?

it writes to the file with elevated priviledges and doesn't write it back to the terminal, effectively a 'sudo sh -c '{cmd} > {file}''.

sudo tee is a common way to work around priviledge restrictions in shell pipes (you can't easily 'sudo' a pipe), if /secure was 0600 and owned by root:

"sudo echo "test" > /secure" or "sudo printf '' > /secure", would not work because your user's shell process can't write to /secure. However, "echo 'test' | sudo tee /secure" works because the elevated 'sudo tee' can write to the file.


Cool, thanks!

I did a "Asteroid as an FPS" a couple months ago, play it here: https://linsomniac.github.io/roidbelt/

The silly part is that you end up just looking at the radar and playing regular Asteroid anyway

The whole reason I made it was that the "top down" view never really clicked for me, so when I'm playing it I almost never look at it.

That’s really cool! Neat cross of the old tank game with the wireframe graphics and asteroids!

Batttlezone was the tank game.

man, I loved that game.


While we're at it, I also did Tempest: https://linsomniac.github.io/teapot/

it's beautiful, well done!

Thanks!

I have tried to forego swap because I had hoped that it would avoid swap thrashing, where performance goes into the toilet; I'd rather a process was killed but I could still access the system, than be unable to login to it.

But I've found that even with no/little swap, the system can get into high memory pressure situations (even easier because it can't swap out unused pages of libraries and the like), and still go into a sort of thrashing state even though it isn't swapping.

My main workstation is a Dell XPS15 with 32GB of RAM and I had 8GB of swap on it. About every month the system load would skyrocket even though it had plenty of mem+cache+swap available. If I killed off my browser and slack, load would return to normal, and I could use the system for a few more days or a week before it happened again.

I struggled with this for a year or more, before (for reason's I don't remember), I added another 8GB of swap. Within the next day 80% of the extra swap was used right up. I decided to swapoff that new file and create a 64GB swapfile and just see what happened. It got to around 20-30GB IIRC before it leveled off. And, more importantly, over the next 100+ days I never had that thrashing happen again.

That was with Ubuntu 22.04. I just recently (May-ish) switched over to a NixOS setup with 64GB of swapfile, and it's been very stable.


Read only pages (most of libraries and binaries) get “paged out” to the file they came from, not swap.

(They obviously don’t page out, they are just discarded and read again when needed)


Yes, only dirty (i.e. modified) pages profit from getting paged out to swap.

But while I don't have any hard data, I imagine that depending on the workload, there can be a punch of pages that are read during initialization, or a one-off workload, and never being read or freed up afterwards.

Just try activating a swap file, and see if it gets any usage, despite memory pressure being low.


When we looked it was always tiny

In the distant past there was plenty of times I tried to fix dying web servers by logging in and restarting a rogue process or cleaning up a memory leak... only to have my SSH session and shell sessions being repeatedly killed by OOMs.

Not as big of a problem as it used to be. Both because OOM killer has gotten better and also web servers are such a commodity that remotely cycling them isn't going to cause a outage and is the quickest and cleanest way to get them back into production.


>only to have my SSH session and shell sessions being repeatedly killed by OOMs

The OOM killer looking at processes and seeing a giant one, using 90% of the physical memory and growing fast and deciding "Oh, that's ok because it is working hard, I'm going to go kill this little tiny thing that hasn't been used recently called sshd". Inoculating sshd against the oom killer is SOP now.


The old rule of thumb used to be 2x actual RAM for your swap file/partition size.

That's probably not right with today's RAM sizes but I'm not sure what the current rule is. I just go with the Ubuntu installer default but I don't know if that's just a fixed number or computed in some way from amount of RAM available.


> The old rule of thumb used to be 2x actual RAM for your swap file/partition size.

Which was always a dumbass rule that made no logical sense.

Like, I remember a time when I had 4 GB of RAM and had my swap set to 8 GB. Then I upgraded to 16 GB of RAM. Theoretically, I shouldn't even need a swap file anymore, since my old setup would max at 12 GB and yet I never had OOM problems, but that "rule of thumb" would dictate that I should increase my swap to 32 GB.


This is why they went on to say it doesn’t make sense with modern RAM sizes.

I remember when I first came across this rule when getting into Linux for the first time. If memory serves, I had 256MB of RAM, so I set swap for 512MB, which seems perfectly cromulent.


Some of that was driven by people wanting hibernation to be reliable.

The other part was that it kinda matched the money you were spending on the machine.

The guy with 128MB of ram could likely afford to spend the extra disk space on a swap partition then the guy stuck with just 32MB.


... but if you buy my book with more of this, I'll send you even more to read!

I get it, sometimes it's fun to follow a story. But I also read a dozen or so paragraphs, then started scrolling, then gave up.


I wonder how much of this is due to the AI tooling being taught on sloppy code that humans have written. Over the last 4 decades I've looked at a lot of code on the Internet and there's a lot of slop out there.

>Are you sure this is a bandwidth issue?

It's technically not a bandwidth issue, AFAIK, it is a "profile" issue. When listening to audio only you are using a different bluetooth profile than when you are using it for two way mic+speakers.

Try playing some music on your computer and then start a video call. Even before I jump into the meeting, as soon as I hit the Google meet site and it opens up the meeting "camera preview" page, the music quality goes straight into the toilet.

This also happens to my "puck" speaker+mic array that is connected via USB.


> This also happens to my "puck" speaker+mic array that is connected via USB.

Argh. Isn’t this direct evidence that it is not the “Bluetooth profile”? Since it’s directly connected via USB?


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: