[HN Gopher] Swift at Apple: Migrating the Password Monitoring Se...
       ___________________________________________________________________
        
       Swift at Apple: Migrating the Password Monitoring Service from Java
        
       Author : fidotron
       Score  : 171 points
       Date   : 2025-06-03 17:03 UTC (5 hours ago)
        
 (HTM) web link (www.swift.org)
 (TXT) w3m dump (www.swift.org)
        
       | quux wrote:
       | I'm hoping to hear some good news at WWDC for swift development
       | in editors other than Xcode (VSCode, Neovim, etc.) Last year they
       | said "we need to meet backend developers where they are" and
       | announced plans to improve sourcekit-lsp and other efforts.
        
         | sureglymop wrote:
         | I hope so too! We even have an official Kotlin LSP now... maybe
         | that serve as inspiration.
        
           | rescripting wrote:
           | Swift has an official LSP:
           | https://github.com/swiftlang/sourcekit-lsp
           | 
           | It was first released 7 years ago.
        
             | sureglymop wrote:
             | Thanks for letting me know! I had no idea...
        
         | candiddevmike wrote:
         | IMO, Apple has quite the track record of never "meeting X where
         | they are". They could make Xcode cross platform, but they never
         | will.
        
           | st3fan wrote:
           | There would be no point in doing that. All the devs they care
           | about already have Macs. If you are on Windows or Linux and
           | you want to work on Swift server side code then you can use
           | their official LSP or VSCode extension in your favorite
           | editor.
        
             | tough wrote:
             | There's always XTool https://github.com/xtool-org/xtool
        
           | klausa wrote:
           | Xcode is probably like, one of the top... 3? 5? biggest
           | macOS-native applications in the world.
           | 
           | Making it cross-platform would require either reimplementing
           | it from scratch, or doing a Safari-on-Windows level of
           | shenanigans of reimplementing AppKit on other platforms.
        
             | AdamN wrote:
             | Xcode on Windows/Linux would be wacky and not worth the
             | effort - it's very tightly coupled to MacOS so effectively
             | impossible imho. People targeting MacOS/iOS aren't
             | typically running Windows on the desktop. The more critical
             | thing to meeting developers where they are would be for the
             | entire developer loop to be doable from a JetBrains IDE on
             | MacOS.
        
               | cosmic_cheese wrote:
               | > People targeting MacOS/iOS aren't typically running
               | Windows on the desktop.
               | 
               | Or if they are, they're treating macOS/iOS as "blind
               | targets" where those platforms are rarely if ever QA'd or
               | dogfooded.
               | 
               | > The more critical thing to meeting developers where
               | they are would be for the entire developer loop to be
               | doable from a JetBrains IDE on MacOS.
               | 
               | I think most current Apple platform devs would be
               | happiest if they were equipped with the tools to build
               | their own IDEs/toolchains/etc, so e.g. Panic's Nova could
               | feasibly have an iOS/macOS/etc dev plugin or someone
               | could turn Sublime Text into a minimalistic Apple
               | platform IDE. JetBrains IDEs certainly have a wide
               | following but among the longtime Mac user devs in
               | particular they're not seen as quite the panacea they're
               | presented as in the larger dev community.
        
             | rafram wrote:
             | > Safari-on-Windows level of shenanigans of reimplementing
             | AppKit on other platforms
             | 
             | I was curious about this, so I downloaded it to take a
             | look. It doesn't look like they actually shipped AppKit, at
             | least as a separate DLL, but they did ship DLLs for
             | Foundation, Core Graphics, and a few other core macOS
             | frameworks.
        
           | paxys wrote:
           | Who even wants Xcode to be cross platform? People can barely
           | tolerate it on macs.
           | 
           | What you really mean is people want the iOS development
           | toolchain to be cross platform, and that would mean porting
           | iOS to run in a hypervisor on linux/windows (to get the
           | simulator to work). That is way too big a lift to make sense.
        
         | st3fan wrote:
         | This project is getting more mature
         | https://github.com/swiftlang/vscode-swift
         | 
         | And https://github.com/swiftlang/sourcekit-lsp an be used in
         | any LSP compatible editor like Neovim.
        
         | lawgimenez wrote:
         | My main wish for Apple this upcoming WWDC is to make Xcode not
         | make my M2 super hot.
        
         | elpakal wrote:
         | Ive wanted this for years. FWIW I've used CLion's Swift plugin
         | for my pure SPM projects and it's actually decent.
        
         | kridsdale1 wrote:
         | I've been writing iOS apps primarily for 15 years. I haven't
         | had to use Xcode since about 2016 since Facebook and Google
         | have fully capable VSCode based editors with distributed builds
         | in the Linux clouds. It's pretty great, but I don't know of an
         | open source version of this system. That is, integration with
         | Bazel/Buck that can build iOS on non-Mac hardware.
        
       | netbioserror wrote:
       | A win on the board for ARC? Can anyone with more deep GC
       | knowledge explain why this might be, considering the tweaks they
       | made to G1? Is this a specific workload advantage, or does it
       | apply generally?
        
         | username223 wrote:
         | It has been a long time, but I worked on GC at one point. My
         | guess is that it's the memory footprint (and loss of cache
         | locality) that's to blame. Copying or mark/sweep can be fast,
         | but only if you give them lots of extra memory to accumulate
         | garbage between GC passes. ARC does a little extra CPU work all
         | the time, but it has good locality, and doesn't need the extra
         | memory.
        
         | adamwk wrote:
         | The way to write performant Swift is classless so without ARC,
         | but classes have been necessary for many areas. Recently,
         | Swift's been leveraging a lot of ownership features similar to
         | Rust to make it possible to do more without classes, and I'd
         | guess Apple teams would be using those
        
           | sunnybeetroot wrote:
           | What areas are classes necessary assuming you're talking
           | about pure Swift and not iOS?
        
             | adamwk wrote:
             | Where copying is expensive (most Swift collections are
             | backed by classes for COW semantics). Where location
             | stability is necessary (where you need a mutex). Resource
             | allocation. Those are the primary examples that noncopyable
             | types are meant to address.
        
       | paxys wrote:
       | > In comparison with the previous Java service, the updated
       | backend delivers a 40% increase in performance, along with
       | improved scalability, security, and availability.
       | 
       | As is always the case with such rewrites, the big question is
       | whether the improvements came from the choice of language or
       | because they updated a crusty legacy codebase and fixed
       | bugs/bottlenecks.
        
         | tiffanyh wrote:
         | I'd typically agree with your comment but ...
         | 
         | Given that they also experienced a 90% reduction in Memory
         | Usage (presumably from Java GC vs Swift AOT memory management)
         | - it seems more likely the gains are in fact from the
         | difference in languages.
        
           | plorkyeran wrote:
           | The typical rule of thumb is that getting good performance
           | out of tracing GC requires doubling your memory usage, so a
           | 90% reduction suggests that they made significant
           | improvements on top of the language switch.
        
             | username223 wrote:
             | I remember the 2x rule from 20 years ago - do you know if
             | things have changed? If locality is more important now,
             | tracing GC might never be as performant as reference
             | counting. Either you use 2x the memory and thrash your
             | cache, or you use less and spend too much CPU time
             | collecting.
        
               | jeroenhd wrote:
               | Java has had AOT compilation for a while, so traditional
               | GC and its massive overhead are no longer a strict
               | necessity. Even AOT Java will probably stay behind Swift
               | or any other natively compiled language in terms of
               | memory usage, but it shouldn't be that drastic.
               | 
               | As for performance and locality, Java's on-the-fly
               | pointer reordering/compression can give it an edge over
               | even some compiled languages in certain algorithms. Hard
               | to say if that's relevant for whatever web framework
               | Apple based their service on, but I wouldn't discount
               | Java's locality optimisations just because it uses a GC.
        
               | username223 wrote:
               | > Java has had AOT compilation for a while, so
               | traditional GC and its massive overhead are no longer a
               | strict necessity.
               | 
               | You mean it does escape analysis and stack-allocates what
               | it can? That would definitely help, but not eliminate the
               | GC. Or are you thinking of something else?
               | 
               | Thinking about it more, I remember that Java also has
               | some performance-hostile design decisions baked in (e.g.
               | almost everything's an Object, arrays aren't packed,
               | dynamic dispatch everywhere). Swift doesn't have that
               | legacy to deal with.
        
               | acdha wrote:
               | Java also has a lot of culture making optimization-
               | resistant code so there's the question of whether you're
               | talking about the language itself or various widespread
               | libraries, especially if they're old enough to have
               | patterns designed around aesthetics or now-moot language
               | limitations rather than performance.
               | 
               | I've replaced Java code with Python a few times and each
               | time even though we did it for maintenance (more Python
               | devs available) we saw memory usage more than halved
               | while performance at least doubled because the code used
               | simpler functions and structures. Java has a far more
               | advanced GC and JIT but at some point the weight of code
               | and indirection wins out.
        
               | cogman10 wrote:
               | It all depends, but one major advantage of the way the
               | JVM GCs is related memory will tend to be colocated. This
               | is particularly true of the serial, parallel, and G1GC
               | collectors.
               | 
               | Let's say you have an object that looks like A -> B -> C.
               | Even if the allocation of A/B/C happened at very
               | temporally different times and inbetween different
               | allocations, the next time the GC runs as it traverses
               | the graph it will see and place in memory [A, B, C]
               | assuming A is still live. That means even if the memory
               | originally looks something like [A, D, B, Q, R, S, T, C]
               | the act of collecting and compacting has a tendency to
               | colocate.
        
             | geodel wrote:
             | That is just GC part. Another big difference is Reference
             | type (Java) vs Value Type (Swift).
        
             | mrighele wrote:
             | The 90% reduction doesn't necessarily have to be related
             | only to GC.
             | 
             | In my experience Java is a memory hog even compared to
             | other garbage collected languages (that's my main gripe
             | about the language).
             | 
             | I think a good part of the reason is that if you exclude
             | primitive types, almost everything in Java is an heap-
             | allocated object and Java objects are fairly "fat": every
             | single instance has an header of between 96 and 128 bit on
             | 64-bit architectures [1]. That's... a lot. Just by making
             | the headers smaller (the topic of the above link) you can
             | get 20% decrease in heap usage and improvements in cpu and
             | GC time [2].
             | 
             | My hope is that once value classes arrive [3][4], and
             | libraries start to use them, we will see a substantial
             | decrease in heap usage in an average java app.
             | 
             | [1] https://openjdk.org/jeps/450
             | 
             | [2] https://openjdk.org/jeps/519
             | 
             | [3] https://openjdk.org/jeps/401
             | 
             | [4] https://www.youtube.com/watch?v=Dhn-JgZaBWo
        
               | formerly_proven wrote:
               | If Java's 128-bit object headers are already fairly fat,
               | then what adjective applies to CPython's? [] is about a
               | whole cache line. Trivial Python objects are barely
               | smaller.
        
               | cogman10 wrote:
               | The java GC approach is somewhat unique compared to other
               | languages. There are multiple GCs and pretty much all of
               | them are moving collectors. That means the JVM fairly
               | rarely ends up freeing memory that it's claimed. A big
               | spike will mean that it holds onto the spike's amount of
               | memory.
               | 
               | Many other GCed languages, such as swift, CPython, Go, do
               | not use a moving collector. Instead, they allocate and
               | pin memory and free it when not in use.
               | 
               | The benefit to the JVM approach is heap allocations are
               | wicked fast on pretty much all its collectors. Generally,
               | to allocate it's a check to see if space is available and
               | a pointer bump. For the other languages, you are bound to
               | end up using a skiplist and/or arena allocator provided
               | by your malloc implementation. Roughly O(log(n)) vs O(1)
               | in performance terms.
               | 
               | Don't get me wrong, the object header does eat a fair
               | chunk of memory. Roughly double what another language
               | will take. However, a lot of people confuse the memory
               | which the JVM has claimed from the OS (and is thus
               | reported by the OS) with the memory the JVM is actively
               | using. 2 different things.
               | 
               | It just so happens that for moving collectors like the
               | JVM typically uses more reserved memory means fewer
               | garbage collections and time spend garbage collecting.
        
           | loxs wrote:
           | The java runtime is a beast. Even the fact that another
           | runtime is just capable to do a similar thing is impressive,
           | disregard the fact that it might be better. Even being on par
           | makes it interesting for me to maybe try it on my own.
        
           | javanonymous wrote:
           | The JVM tends to use as much memory as it can for performance
           | reasons. It is not a reliable indicator of how much memory it
           | _actually_ needs. Why spend resources on clearing memory if
           | there 's still unused memory left?
           | 
           | If memory is an issue, you can set a limit and the JVM will
           | probably still work fine
        
         | BonoboIO wrote:
         | Imagine what rust or go could have achieved
        
           | dontlaugh wrote:
           | Go is similar to Swift when it comes to mandatory costly
           | abstractions.
           | 
           | It's only Rust (or C++, but unsafe) that have mostly zero-
           | cost abstractions.
        
             | frizlab wrote:
             | Swift have them too now (non-Copyable types).
        
             | airspeedswift wrote:
             | Swift, Rust, and C++ all share the same underlying
             | techniques for implementing zero-cost abstrations
             | (primarily, fully-specialized generics). The distinction in
             | Swift's case is that generics can also be executed without
             | specialization (which is what allows generic methods to be
             | called over a stable ABI boundary).
             | 
             | Swift and Rust also allow their protocols to be erased and
             | dispatched dynamically (dyn in Rust, any in Swift). But in
             | both languages that's more of a "when you need it" thing,
             | generics are the preferred tool.
        
               | dontlaugh wrote:
               | To an approximation, but stdlib and libraries will have a
               | bias. In practice, abstractions in Rust and C++ more
               | commonly are actually zero-cost than in Go or Swift.
               | 
               | This is not a bad thing, I was just pointing out that Go
               | doesn't have a performance advantage over Swift.
        
             | rafram wrote:
             | > It's only Rust (or C++, but unsafe) that have mostly
             | zero-cost abstractions.
             | 
             | This just isn't true. It's good marketing hype for Rust,
             | but any language with an optimizing compiler (JIT or AOT)
             | has plenty of "zero-cost abstractions."
        
         | favorited wrote:
         | The post notes that the user-facing app was "introduced in the
         | fall of 2024," so presumably the services aren't _that_ legacy.
        
           | remus wrote:
           | You can learn a lot when writing V2 of a thing though. You've
           | got lots of real world experience about what worked and what
           | didn't work with the previous design, so lots of opportunity
           | for making data structures that suit the problem more closely
           | and so forth.
        
         | misiek08 wrote:
         | I love to always see such comments. On JVM you use crap like
         | Spring and over-engineer everything. 20 types, interfaces and
         | objects to keep single string in memory.
         | 
         | JVM also like memory, but can be tailored to look okayish,
         | still worse than opponents.
        
           | bdangubic wrote:
           | same - in every single language with incompetent team
        
           | paxys wrote:
           | And I'm 100% sure you can do the same in Swift.
        
             | jen20 wrote:
             | Swift's limitations around reflection actually make it
             | surprisingly difficult to create a typical Java-style mess
             | with IOC containers and so forth.
        
             | eikenberry wrote:
             | It's not technical, it's cultural. Different community
             | conventions.
        
             | jbverschoor wrote:
             | Sure, And you can also make beautiful code in php, or shot
             | code in Java
             | 
             | It's the history, standard libs, and all the legacy
             | tutorials which don't get erased from the net
        
         | Someone wrote:
         | My $0.02 is that Java not having value types (yet), while Swift
         | has, is a large reason for the efficiency gains.
        
           | CharlieDigital wrote:
           | As a C# dev, I guess I've just taken it for granted that we
           | have value types. Learned something new today (that Java
           | apparently does not).
        
             | MBCook wrote:
             | It does for primitives.
             | 
             | For user defined stuff we've recently gained records, which
             | are a step in that direction, and a full solution is
             | coming.
        
               | SigmundA wrote:
               | What about structs?
        
               | cogman10 wrote:
               | I'm not sure with the semantics of structs for C#.
               | 
               | What java is getting in the future is immutable data
               | values where the reference is the value.
               | 
               | When you have something like                  class Foo {
               | int a;          int b;        }             var c = new
               | Foo();
               | 
               | in java, effectively the representation of `c` is a
               | reference which ultimately points to the heap storage
               | locations of `a, b`. In C++ terms, you could think of the
               | interactions as being `c->b`.
               | 
               | When values land, the representation of `c` can instead
               | be (the JVM gets to decide, it could keep the old
               | definition for various performance reasons) something
               | like [type, a, b]. Or in C++ terms the memory layout can
               | be analogous to the following:                   struct
               | Foo { int a, int b };              struct Foo c;
               | c.a = 1;         c.b = 2;
        
         | rs186 wrote:
         | Yes! The post would have been much more informative if it did
         | an in-depth analysis of where the performance gain comes from.
         | But Apple being Apple, I don't think they'll ever want to
         | expose details on their internal systems, and we probably can
         | only get such hand wavy statements.
        
           | MBCook wrote:
           | I suspect that didn't fit into the goal of the blog post.
           | 
           | I don't think it's meant to be a postmortem on figuring out
           | what was going on and a solution, but more a mini white paper
           | to point out Swift can be used on the server and has some
           | nice benefits there.
           | 
           | So the exact problems with the Java implementation don't
           | matter past "it's heavy and slow to start up, even though it
           | does a good job".
        
         | gt0 wrote:
         | Agree, this is almost _always_ where the benefits come from.
         | You get to write v2 of the software with v1 to learn from.
        
         | mpweiher wrote:
         | With the 90% reduction in memory consumption, I'd wager that
         | most if not all the performance improvement came from that. In
         | fact, it is a little surprising that hardware utilization only
         | dropped 50%.
         | 
         | Reduced memory consumption for cloud applications was
         | apparently also the primary reason IBM was interested in Swift
         | for a while. Most cloud applications apparently sit mostly idle
         | most of the time, so the number of clients you can multiplex on
         | single physical host is limited by memory consumption, not CPU
         | throughput.
         | 
         | And Java, with the JIT and the GC, has horrible memory
         | consumption.
        
           | dgs_sgd wrote:
           | Interesting. If IBM was trying to solve for memory
           | consumption, why do you think they picked Swift over
           | alternatives that might also have achieved lower memory
           | consumption?
        
         | tialaramex wrote:
         | Sure, maybe you can get money to have some businesses try out
         | rewriting their line-of-business software in the same language
         | versus in a different language and get some results.
         | 
         | My expectation is that if you put the work in you can get
         | actual hard numbers, which will promptly be ignored by every
         | future person asking the same "question" with the same implied
         | answer.
         | 
         | If the "just rewrite it and it'll be better" people were as
         | right as they often seem to believe they are, a big mystery is
         | JWZ's "Cascade of Attention-Deficit Teenagers" phenomenon. In
         | this scenario the same software is rewritten, over, and over,
         | and over, yet it doesn't get faster and doesn't even fix many
         | serious bugs.
        
       | YooLi wrote:
       | Any idea of what the server platform is? Linux?
        
         | ezfe wrote:
         | Almost certainly
        
         | paxys wrote:
         | Can't really imagine what else it would be.
        
           | MBCook wrote:
           | Apple is known to use Linux on servers, but I could see a
           | case for BSD being in the running.
           | 
           | The macOS userland is based on BSD so you'd get a nice little
           | fit there. And it's not like some common BSD is bad at doing
           | the job of a server. I know it can do great things.
           | 
           | Who knows if it was ever discussed. They wouldn't want
           | Windows (licensing, optics, etc) and macOS isn't tuned to be
           | a high performance server. Linux is incredibly performant and
           | ubiquitous and a very very safe choice.
        
             | cosmic_cheese wrote:
             | Another BSD that Apple used at one point was NetBSD, which
             | is what they ran on their AirPort wireless routers prior to
             | their discontinuation.
        
         | cosmic_cheese wrote:
         | In this case probably Linux, but Apple also uses custom
         | M-series based servers running a hardened Darwin-based OS for
         | LLM processing of user data.
        
           | gorbypark wrote:
           | I really really want some kind of write up on that custom
           | m-series hardware. Not very much has even leaked out.
        
         | timsneath wrote:
         | It runs on Linux-based infrastructure. We've updated the blog
         | post to clarify this. Thanks!
        
           | latchkey wrote:
           | Which Linux?
        
         | dale_huevo wrote:
         | It's well-known Apple is a big RHEL customer, including Linux
         | on Azure, lending credence to the saying that every Mac is
         | built upon Windows (Hyper-V).
         | 
         | Fairly certain the iTunes store, their web store, etc. are all
         | built upon enterprise Linux as well.
         | 
         | And there's nothing wrong with that. Use the best tool for the
         | job. Most car owners have never looked in the engine
         | compartment.
        
           | gorbypark wrote:
           | I don't think many azure services are Linux on hyper-v, are
           | they? Azure (afaik) is quite heavy on bare metal Linux.
        
           | jen20 wrote:
           | > including Linux on Azure
           | 
           | Are you sure about this?
        
       | zapnuk wrote:
       | Very interesting. I wish they had gone into a little more detail
       | about the other technologies involved.
       | 
       | Was the Java Service in Spring (boot)?
       | 
       | What other technologies were considerd?
       | 
       | I'd assume Go was among them. Was it just the fact that Go's type
       | system is to simplistic or what were the other factors?
        
         | geodel wrote:
         | Swift is Apple's own language. They have all the experts from
         | lowest to highest level .
         | 
         | Writing a long winded report/article for fair technical
         | evaluation of competing technologies would utter waste of time
         | and no one would believe if answer were still Swift.
         | 
         | > I'd assume Go was among them. ...
         | 
         | I don't see any reason to evaluate Go at all.
        
           | latchkey wrote:
           | > I don't see any reason to evaluate Go at all.
           | 
           | https://devblogs.microsoft.com/typescript/typescript-
           | native-...
        
             | dontlaugh wrote:
             | That still seems like a long term mistake to me, an
             | evolutionary dead end.
        
               | latchkey wrote:
               | Does it matter? Today, they get a 10x improvement by
               | switching. Mission accomplished.
               | 
               | X years from now, another language will come along and
               | then they can switch to that for whatever benefit it has.
               | It is just the nature of these things in technology.
        
               | dontlaugh wrote:
               | It can be a limitation much faster than that. They are in
               | a situation where they won't be able to improve further
               | by much due to unavoidable costly abstractions in Go. If
               | they'd picked something lower level there would be more
               | possible after this first switch.
        
               | latchkey wrote:
               | My mistake, I shouldn't have put a number there since
               | that is what you focused on.
               | 
               | Rewriting it in assembly is the way to go, but that has
               | other tradeoffs.
        
               | dontlaugh wrote:
               | I'm not focused on a number, I'm just pointing out Go's
               | optimisation potential is lower than other options.
               | 
               | Of course it's a trade off and their reasons are fine,
               | but rewrites are expensive and disruptive. I would have
               | picked something that can avoid a second rewrite later
               | on.
        
             | MBCook wrote:
             | But that ignores the fact Apple has a MASSIVE investment in
             | Swift.
             | 
             | I think they already use Go in places, but they've clearly
             | stated their intention to use Swift as much as possible
             | where it's reasonable.
             | 
             | I suspect they didn't evaluate C++, Rust, Go, Erlang, Node,
             | and 12 other things.
             | 
             | They have the experience from other Swift services to know
             | it will perform well. Their people already know and use it.
             | 
             | If Swift (and the libraries used) weren't good enough
             | they'd get their people to improve it and then wait to
             | switch off Java.
             | 
             | If you go to a Java shop and say you want to use C# for
             | something Java can do, they'll probably say to use Java.
             | 
             | I don't read this post as "Swift is the best thing out
             | there" but simply "hey Swift works great here too where you
             | might not expect, it's an option you might not have known
             | about".
        
               | latchkey wrote:
               | Microsoft has a massive investment in C#, but they still
               | evaluated (and picked) golang.
        
               | MBCook wrote:
               | For TypeScript's compiler, yes. I can see some real
               | benefits, like Go is already common for some open source
               | software they want to collaborate with non-MS people on.
               | I suspect C# is much less common for that, and when
               | targeting pure performance I suspect a bytecode language
               | like C# wouldn't have the same large gain.
               | 
               | I'm not in the .NET ecosystem so I don't know if native
               | AOT compilation to machine code is an option.
               | 
               | But anyway, in this case Apple is making an internal
               | service for themselves. I think a better comparison for
               | MS would be if they chose to rewrite some Windows
               | service's server back end. Would they choose Go for that?
               | 
               | I don't know.
        
               | latchkey wrote:
               | The real question isn't whether they would choose it, but
               | whether they'd be willing to evaluate it. Given their
               | past behavior, as I mentioned above, it seems they are
               | open to assessing options and selecting the best tool for
               | the job.
        
         | anuragsoni wrote:
         | Apple maintains servicetalk[1] (java networking framework built
         | on top of netty), so I'm guessing this is one potential JVM
         | framework that was being used.
         | 
         | [1] https://github.com/apple/servicetalk
        
       | maz1b wrote:
       | I've always wondered a slight amount as to why larger enterprises
       | (which have the resources to hire specialists) don't hire people
       | with expertise in say things like Rust, or Elixir/Phoenix?
       | 
       | It's one thing to say that we want to hire commonly available
       | developers like in Java or C#, but if you have a long term plan
       | and execution strategy, why not pick technology that may pay off
       | larger dividends?
       | 
       | ITT: I get why they chose Swift, it's Apple's own in house
       | technology. Makes total sense, not knocking that at all. Nice
       | writeup.
        
         | geodel wrote:
         | Many reasons:
         | 
         | There are not enough Rust experts in the world for a typical
         | enterprise to hire and benefit from it.
         | 
         | Elixir/Phoenix are not order of magnitude improvements over
         | Java like Rust, they are marginal improvements. Enterprise
         | don't care for that.
        
         | neepi wrote:
         | It's because Java and c# are so commoditised we don't have to
         | pay people as much.
         | 
         | Also it's about short term balance sheet not long term product
         | management in the SME and small SaaS space. I don't think
         | anyone other then the developers give a shit.
        
         | manmal wrote:
         | They do have Elixir positions, eg https://jobs.apple.com/en-
         | us/details/200562288/senior-softwa...
        
       | maximilianroos wrote:
       | > One of the challenges faced by our Java service was its
       | inability to quickly provision and decommission instances due to
       | the overhead of the JVM. ... To efficiently manage this, we aim
       | to scale down when demand is low and scale up as demand peaks in
       | different regions.
       | 
       | but this seems to be a totally asynchronous service with
       | extremely liberal latency requirements:
       | 
       | > On a regular interval, Password Monitoring checks a user's
       | passwords against a continuously updated and curated list of
       | passwords that are known to have been exposed in a leak.
       | 
       | why not just run the checks at the backend's discretion?
        
         | lilyball wrote:
         | > _why not just run the checks at the backend 's discretion?_
         | 
         | Presumably it's a combination of needing to do it while the
         | computer is awake and online, and also the Passwords app
         | probably refreshes the data on launch if it hasn't updated
         | recently.
        
         | potatolicious wrote:
         | > _" why not just run the checks at the backend's discretion?"_
         | 
         | Because the other side may not be listening when the compute is
         | done, and you don't want to cache the result of the computation
         | because of privacy.
         | 
         | The sequence of events is:
         | 
         | 1. Phone fires off a request to the backend. 2. Phone waits for
         | response from backend.
         | 
         | The gap between 1 and 2 cannot be long because the phone is
         | burning battery the entire time while it's waiting, so there
         | are limits to how long you can reasonably expect the device to
         | wait before it hangs up.
         | 
         | In a less privacy-sensitive architecture you could:
         | 
         | 1. Phone fires off request to the backend. Gets a token for
         | response lookup later. 2. Phone checks for a response later
         | with the token.
         | 
         | But that requires the backend to hold onto the response, which
         | for privacy-sensitive applications you don't want!
        
           | maximilianroos wrote:
           | thanks!
        
           | ivan_gammel wrote:
           | Is it really a problem? Client can pass an encryption key
           | with the request and then collect encrypted result later. As
           | long as computation is done and result is encrypted, server
           | can forget the key, so cache is no longer a privacy concern.
        
             | potatolicious wrote:
             | You can, and in situations where the computation is
             | unavoidably long that's what you'd do. But if you can do a
             | bit of work to guarantee the computation is fast then it
             | removes a potential failure mode from the system - a
             | particularly nasty one at that.
             | 
             | If you forget to dump the key (or if the deletion is not
             | clean) then you've got an absolute whopper of a privacy
             | breach.
             | 
             | Also worth noting that you can't dump the key until the
             | computation is complete, so you'd need to persist the key
             | in some way which opens up another failure surface. Again,
             | if it can't be avoided that's one thing, but if it can
             | you'd rather not have the key persist at all.
        
           | paxys wrote:
           | Especially since the request contains the user's (hashed)
           | passwords. You definitely don't want to be holding that on
           | the server for longer than necessary.
        
       | misiek08 wrote:
       | I would love to see such post from Microsoft about C#. "We looked
       | into few alternatives and chose our own language, it fitted the
       | task, worked great and came as best overall in terms of
       | technology, devex and maintainability".
       | 
       | Great read, thanks for sharing! This means to me you are mature,
       | sharing stuff instead of making obscure secrets from basic stuff
       | existing at many companies <3
        
         | fmorel wrote:
         | They've done quite a few user stories on
         | https://devblogs.microsoft.com/dotnet/category/developer-sto...
         | and related blogs, especially about .NET Framework to .NET
         | migrations.
        
       | ohdeargodno wrote:
       | >Java's G1 Garbage Collector (GC) mitigated some limitations of
       | earlier collectors
       | 
       | The... existing and default GC since JDK 6 G1GC ?
       | 
       | >managing garbage collection at scale remains a challenge due to
       | issues like prolonged GC pauses under high loads, increased
       | performance overhead, and the complexity of fine-tuning for
       | diverse workloads.
       | 
       | Man if only we had invented other garbage collectors like ZGC
       | (https://openjdk.org/jeps/377) since JDK15 or even Shenandoah
       | (https://wiki.openjdk.org/display/shenandoah/Main) backported all
       | the way to JDK8 that have goals of sub millisecond GC pauses and
       | scale incredibly well to even terabytes of RAM. Without really a
       | need to tune much of the GC.
       | 
       | > inability to quickly provision and decommission instances due
       | to the overhead of the JVM
       | 
       | Man if only we invented things like AOT compilation in Java and
       | even native builds. We could call it GraalVM or something
       | (https://www.graalvm.org/)
       | 
       | >In Java, we relied heavily on inheritance, which can lead to
       | complex class hierarchies and tight coupling.
       | 
       | Man if only you could literally use interfaces the same way you
       | use protocols. Imagine even using a JVM language like Kotlin that
       | provides interface delegation! I guess we'll have to keep
       | shooting ourselves in the foot.
       | 
       | >Swift's optional type and safe unwrapping mechanisms eliminate
       | the need for null checks everywhere, reducing the risk of null
       | pointer exceptions and enhancing code readability.
       | 
       | I'll grant them this one. But man, if only NullAway existed :(
       | 
       | >Swift's async/await support is a nice addition, streamlining how
       | we handle async tasks.[ ... ] We can now write async code that
       | reads like sync code
       | 
       | Putting aside the fact that Swift's whole MainActor based async
       | story is so shit that I'd enjoy writing async in Rust with tokio
       | and that Swift 6 is the cause of so many headaches because their
       | guidelines on async have been terrible: Man, if only the JDK
       | included things like virtual threads that would make writing
       | async code feel like sync code with a tiny wrapper around. We
       | could call such a thing that collects many threads... A Loom!
       | (https://openjdk.org/projects/loom/)
       | 
       | >Overall, our experience with Swift has been overwhelmingly
       | positive and we were able to finish the rewrite much faster than
       | initially estimated
       | 
       | You rewrote an existing service with existing documentation using
       | a language and libraries you entirely control and it was fast ?
       | Wow!
       | 
       | >In addition to an excellent support system and tooling, Swift's
       | inherent emphasis on modularity and extensibility
       | 
       | I would rather rewrite all my build scripts in Ant scripts that
       | call `make` manually before calling SPM "excellent tooling", but
       | okay.
       | 
       | Anyways, sorry for the sarcasm, but this is just an Apple ad for
       | Apple's Swift Language. Writing low allocation Java code is
       | possible, and while writing efficient arenas is not possible...
       | Java's GC generations are arenas. In the same way, yes, it's more
       | performant. Maybe because their indirection heavy, inheritance
       | abuse led to pointer chasing everywhere, and not having this
       | opportunity in Swift means they can't waste that performance ?
       | Most of what's holding performance back is coding standards and
       | bad habits written at a dark time where the Gang of Four had
       | burrowed its way into every programmer's mind. Add in some
       | reflection for every endpoint because Java back then really loved
       | that for some reason (mostly because writing source generation
       | tasks, or compiler plugins was absolute hell back then, compared
       | to just the "meh" it is today). With a bit of luck, any network
       | serialization also used reflection (thanks GSON & Jackson) and
       | you know just where your throughput has gone.
       | 
       | They had extremely verbose, existing Java 8 code, and just
       | decided to rewrite them using Swift because that's most of what
       | happens at Apple these days. Anything outlined in this post is
       | just post-hoc rationalization. Had it failed, this post would
       | have never happened. Modern Java, while still a bit rough in
       | parts (and I absolutely understand preference in language, I'd
       | much rather maintain something I enjoy writing into) can and will
       | absolutely compete in every aspect with Swift. It just requires
       | getting rid of bad habits, that you (cannot/never learned to)
       | write in Swift
       | 
       | Also I've never had Java tell me it can't figure out the type of
       | my thirty chained collector calls, so maybe Hindley-Milner was
       | not the place to go.
        
         | geodel wrote:
         | Well, Apple is not gonna use and promote Swift, who will? They
         | surely can't count on you for that role.
        
           | ohdeargodno wrote:
           | You can use and promote Swift without being disingenuous.
           | 
           | Swift has some great attributes, and is almost a very
           | pleasant systems language, give or take some sides that can
           | be mostly attributed to Apple going "we need this feature for
           | iOS apps".
           | 
           | An adticle that merely provides some unverifiable claims
           | about how much better it is for them (that represent a large
           | percentage of the best knowledge about Swift on Earth) is
           | about as useful as an AI generated spam site. Anyone making
           | decisions about using Swift on the backend with this post
           | would be a clown.
        
         | Daedren wrote:
         | The funny part is that there's probably zero chance they used
         | Swift 6 for this, because it's impossible to have released
         | Swift 6 without having, you know, actually used the language
         | for something.
        
       | mring33621 wrote:
       | I understand there may be some bias in this article, but the
       | resource usage improvements are hard to ignore for a company that
       | pays for cloud compute/memory usage.
       | 
       | I'm gonna look into server-side Swift.
       | 
       | Looks like it'll take some fiddling to find the right non-xcode
       | tools approach for developing on linux.
       | 
       | I prefer Jetbrains tools over VSCode, if anyone has any hints in
       | that direction.
        
         | dhosek wrote:
         | I don't know that there's anything that magical about Swift in
         | particular, but rather the difference of running without the
         | big runtime of the JVM and the advantages of memory management.
         | Go will probably give improvements (and likely be an easier
         | mental adjustment from a JVM language), and Rust, once you
         | mentally adapt to its model will give even bigger improvements.
         | Swift has the advantage of being object-oriented (if that's an
         | advantage in your mind), but I was thinking 10 years ago that
         | with the move to microservices that Java/Spring apps were going
         | to not work so great with the quick start-up/shut-down that the
         | cloud/microservice model wants.
        
           | manmal wrote:
           | Will Rust really be better than Swift in such a context?
           | Doesn't that more or less depend on what kind of memory
           | management is being used in Rust?
        
         | pharaohgeek wrote:
         | Sadly, Jetbrains no longer sells AppCode or supports their
         | Swift plugins for CLion. I WISH they would open source the
         | plugins, as CLion is far superior to Xcode. For now, though,
         | we're really stuck with either Xcode (Mac) or VSCode
         | (wherever). That said, I am really starting to love server-side
         | Swift using Vapor. Swift, as a language, is great to develop
         | in.
        
       | latchkey wrote:
       | "A faster bootstrap time is a crucial requirement to support this
       | dynamic scaling strategy."
       | 
       | Google AppEngine has been doing this successfully for a decade.
       | It is not easy, but it is possible.
        
       | 5cott0 wrote:
       | now fix AppStore Connect
        
       | sylens wrote:
       | I'd like to give server-side Swift a go but it's hard when the
       | best tooling is tied to one platform.
        
         | manmal wrote:
         | In case you mean Xcode with ,,best tooling", I'd disagree. I
         | spend 8h every day with Xcode, and find VSCode often
         | preferable. I'd just give it a go on Linux tbh.
        
       | StackRiff wrote:
       | I wonder what Apple is using for production monitoring,
       | observability, and performance profiling with swift applications
       | on Linux. In my experience this is one of the key missing pieces
       | in Swift server ecosystem.
       | 
       | You can link against jemalloc, and use google perftools to get
       | heap and CPU profiles, but it's challenging to make good use of
       | them especially with swifts method mangling and aggressive
       | inlining.
        
       | msie wrote:
       | This looks cool except that I see them use Cassandra in their
       | stack. I was using an old version of Cassandra and found it a
       | nightmare to admin.
        
       | schlch wrote:
       | I did some iOS development last year. I did not like the iOS part
       | of it but swift itself feels nice.
       | 
       | Is swift web yet?
        
       | mtrovo wrote:
       | Without a deeper profiling analysis of the Java application it's
       | hard to not consider this whole piece just advertorial content.
       | Where exactly were the bottlenecks in Java or top delta gains
       | compared to Swift. The service scope looks so simple that there
       | might be some underlying problem with the previous version, be it
       | the code not scaling well with the irregular batch nature of
       | traffic or custom cryptography code not taking advantage of the
       | latest native IO constructs.
       | 
       | And I'm not defending Java by any means, more often than not Java
       | is like an 80s Volvo: incredibly reliable, but you'll spend more
       | time figuring out its strange noises than actually driving it at
       | full speed.
        
         | CharlesW wrote:
         | > _Without a deeper profiling analysis of the Java application
         | it 's hard to not consider this whole piece just advertorial
         | content._
         | 
         | I'd be surprised if anything Apple wrote would satisfy you. TFA
         | makes it clear that they first optimized the Java version as
         | much as it could be under Java's GC, that they evaluated
         | several languages (not just Swift) once it became clear that a
         | rewrite was necessary, that they "benchmarked performance
         | throughout the process of development and deployment", and they
         | shared before/after benchmarks.
        
           | cogman10 wrote:
           | Ok, I'm pretty skeptical that they actually did optimize what
           | they could. In fact, reading between the lines it sounds like
           | they barely tried at all.
           | 
           | For example, they mention G1GC as being better than what was
           | originally there but not good enough. Yet the problems they
           | mention, prolonged GC pauses, indicates that G1GC was not the
           | right collector for them. Instead, they should have been
           | using ZGC.
           | 
           | The call out of G1GC as being "new" is also pretty odd as it
           | was added to the JVM in Java 9, released in 2016. Meaning,
           | they are talking about a 9 year old collector as if it were
           | brand new. Did they JUST update to java 11?
           | 
           | And if they are complaining about startup time, then why no
           | mention of AppCDS usage? Or more extreme, CRaC? What about
           | doing an AOT compile with Graal?
           | 
           | The only mention they have is the garbage collector, which is
           | simply just one aspect of the JVM.
           | 
           | And, not for nothing, the JVM has made pretty humongous
           | strides in startup time and GC performance throughout the
           | versions. Theres pretty large performance wins going from
           | 11->17 and 17->21.
           | 
           | I'm sorry, but this really reads as Apple marketing looking
           | for a reason to tout swift as being super great.
        
       | time4tea wrote:
       | Absolute bs.
       | 
       | This falls into the category of "we rewrote a thing written by
       | people that didn't know what they were doing, and it was better"
       | 
       | Large class hierarchies (favour composition over inheritance
       | since 1990!), poorly written async code (not even needed in java,
       | due to virtual threads), poor startup times (probably due to
       | spring), huge heaps sizes (likely memory leaks or other poor
       | code, compounded by inability to restart due to routing and poor
       | startup times)
       | 
       | Yawn.
        
       | jbverschoor wrote:
       | The amount of Apple hate is staggering. Replace swift with rust,
       | And this would have 10x the upvotes and only positive hype
        
       | cogman10 wrote:
       | I'm honestly very skeptical that Apple actually did everything
       | they could to make Java startup fast and the GC perform well
       | under load.
       | 
       | G1GC is a fine collector, but if pause time is really important
       | they should have used ZGC.
       | 
       | And if startup is a problem, recent versions of Java have
       | introduced AppCDS which has gotten quite good throughout the
       | releases.
       | 
       | And if that wasn't good enough, Graal has for a long time offered
       | AOT compilation which gives you both fast startup and lower
       | memory utilization.
       | 
       | None of these things are particularly hard to add into a build
       | pipeline or deployment, they simply require Apple to use the
       | latest version of Java.
        
       ___________________________________________________________________
       (page generated 2025-06-03 23:00 UTC)