While the answer by Irvin Chan did manage to disable the caching behavior of Apollo, I found through profiling that it doesn't actually completely disable it; behind the scenes, it is still adding content to the cache, it's just that the cache is not being used.
This was a problem in my case, because the caching behavior itself was causing a noticeable performance impact on my app. (~1s of processing overhead, over a heavy data-loading period of ~20s, ie. ~5% of the cpu-time wasted)
To fix this, I created this empty alternative to InMemoryCache:
import {ApolloCache, NormalizedCacheObject} from "web-vcore/nm/@apollo/client.js";
const emptyCacheObj = {};
export class VoidCache extends ApolloCache<NormalizedCacheObject> {
    read(options) { return null; }
    write(options) { return undefined; }
    diff(options) { return {}; }
    watch(watch) { return ()=>{}; }
    async reset() {} // eslint-disable-line
    evict(options) { return false; }
    restore(data) { return this; }
    extract(optimistic) { return emptyCacheObj; }
    removeOptimistic(id) {}
    batch(options) { return undefined as any; }
    performTransaction(update, optimisticId) {}
    recordOptimisticTransaction(transaction, optimisticId) {}
    transformDocument(document) { return document; }
    transformForLink(document) { return document; }
    identify(object) { return undefined; }
    gc() { return [] as string[]; }
    modify(options) { return false; }
    readQuery(options, optimistic?) { return null; }
    readFragment(options, optimistic?) { return null; }
    writeQuery(opts) { return undefined; }
    writeFragment(opts) { return undefined; }
    updateQuery(options, update) { return null; }
    updateFragment(options, update) { return null; }
}
And I connected it to Apollo client, like so:
apolloClient = new ApolloClient({
    // replace InMemoryCache with VoidCache, because even a "not used" InMemoryCache can have noticeable overhead
    cache: new VoidCache(),
    // these config-changes might not be necessary, but I've kept them anyway
    defaultOptions: {
        watchQuery: {
            fetchPolicy: "no-cache",
            errorPolicy: "ignore",
        },
        query: {
            fetchPolicy: "no-cache",
            errorPolicy: "all",
        },
    },
});
It seems to be working well so far (avoiding the perf-loss), but I'll update this answer if there's something wrong with it and it needs tweaking.
(Note: The structure of apollo-client's cache has changed over time. My answer above only shows the working structure as of @apollo/client version 3.7.15. Check answer history if you need the structure for older versions: 3.5.0-beta.4.)