Smart placement

Hi! Does smart placement only make sense for single region databases? If I have multiple read replicas for my DB how would CF figure out where to place the worker?
15 Replies
vassbence
vassbence•11mo ago
My database is not a cloudflare database (it's a global dynamodb table with 3 regions) Yeah so its helpful for single region DBs where it can easily be determined where that single DB is and its messy once we go multi region for the DB and i'm just better off with smart turned off Also I try my best to not do more than one DB access per HTTP request and so Smart Placement wouldnt matter any ways I guess because it only helps in use cases with multiple trips if i understand correctly And I guess thats techinically correct as in a single request case it does not matter where the DB, Worker and User are as it will travel the same amount of distance and only once It's even benefical that the Worker is on the edge as the request enters the backbone network faster if my napkin math is correct 😄
Chaika
Chaika•11mo ago
Smart Placement is just bouncing your request from a local to a remote colo. You'd still get on the Cloudflare Network at the same point, your request would just get bounced to the remote colo where the workerr would actually run. Technically there is one advantage to smart placement and single requests that I know of -- that being cache in your worker would be remote cache for that colo and not local, so you might have higher hit % (that is, if you are even using workers cache api, and any cache advantage would be certainly offput by the fact that you have 3 regions and would only use one with smart placement iirc)
vassbence
vassbence•11mo ago
Do you guys happen to know how to do a DNS txt query from workers? DNS over HTTPS is super slow and the native node package is not supported in workers
Chaika
Chaika•11mo ago
Yea DoH shouldn't be that slow. I don't think there's any pretty way of doing direct DNS right now, and ironically you can't use 1.1.1.1, have to use 8.8.8.8/9.9.9.9 because of the CF IP Restrictions on connect(), but it is possible. I used: https://github.com/mafintosh/dns-packet and then you can just send and decode using connect, DNS isn't too complex of a protocol thankfully
vassbence
vassbence•11mo ago
so its possible to run these DNS queries natively in a worker with connect()?
Chaika
Chaika•11mo ago
Possible? Yea. Recommended? Eh Using DoH is much simpler and easier. Keep in mind connect() is TCP only, and while DNS I believe in theory should be fully both protocols supported, in reality that can differ. I have a worker doing just that: https://connect-dns-worker.workers.chaika.me/?type=A&name=google.com. I would just use DoH eitherway though. If Cloudflare is slow for whatever reason, maybe try Google's: https://developers.google.com/speed/public-dns/docs/doh/json
vassbence
vassbence•11mo ago
yeah thats why i was confused, if connect is TCP only and DNS is UDP.. how? 😄
Chaika
Chaika•11mo ago
because DNS is both
vassbence
vassbence•11mo ago
i see, my bad 🙂 thanks for the input! i'll experiment with DoH. My gameplan is to have a latency based TXT DNS recordin aws route53 and I query for this TXT record to figure out the closest region where my db has a replica Feels hacky but it's actually what AWS recommends for their similar lambda@edge service yeah DoH is around 15-50 ms, not sure I can afford this, at this point I can use a single region DB in us-east-1
Chaika
Chaika•11mo ago
I don't think direct tcp dns would be much fasterr then that, perhaps you could do the logic on your worker, the request.cf property contains the .city .region .country, .latitiude and .longtitude , you could use that to pick the fastest, or maybe just use the cache api and cache what the DNS Record returned manually
vassbence
vassbence•11mo ago
.continent should be good enough actually DNS has the added benefit of disabling regions (e.g. they are down) well.. if i don't cache it for too long that is
const CLOSEST_DATABASE_PER_CONTINENT_CODE: { [key: string]: string } = {
// Africa
AF: "eu-central-1",
// Asia
AS: "ap-southeast-1",
// Europe
EU: "eu-central-1",
// North America
NA: "us-east-1",
// South America
SA: "us-east-1",
// Oceania
OC: "ap-southeast-1",
// Antarctica
AN: "ap-southeast-1",
};

function getDatabaseRegion(request: Request, env: Env) {
if (env.DATABASE_SETUP === "single-region") {
return CLOSEST_DATABASE_PER_CONTINENT_CODE["NA"];
}

return CLOSEST_DATABASE_PER_CONTINENT_CODE[
(request.cf?.continent as string) ?? "NA"
];
}
const CLOSEST_DATABASE_PER_CONTINENT_CODE: { [key: string]: string } = {
// Africa
AF: "eu-central-1",
// Asia
AS: "ap-southeast-1",
// Europe
EU: "eu-central-1",
// North America
NA: "us-east-1",
// South America
SA: "us-east-1",
// Oceania
OC: "ap-southeast-1",
// Antarctica
AN: "ap-southeast-1",
};

function getDatabaseRegion(request: Request, env: Env) {
if (env.DATABASE_SETUP === "single-region") {
return CLOSEST_DATABASE_PER_CONTINENT_CODE["NA"];
}

return CLOSEST_DATABASE_PER_CONTINENT_CODE[
(request.cf?.continent as string) ?? "NA"
];
}
lookin' good 😛 Has the cf-placement header been removed from requests? @skye_31 I'm not getting it with smart placement turned on 😦
Chaika
Chaika•11mo ago
Still exists for me Should be either remote- or local- I'm guessing you're talking about enabling it on a different worker? Woulodn't make sense to have it on for the worker trying to use the closest db
vassbence
vassbence•11mo ago
I have it turned on yet it's not showing up as a header might be something on my end Anyways.. multi region db is a bad idea with workers and single region with smart placement is almost always faster Because if the edge location on the multi-region db deployment is far away from the db the roundtrips add up to more than if we'd just go to the single region db
Chaika
Chaika•11mo ago
I think that's more just a function of how many regions you have. If you have one in most regions/close enough to most users, then it would be better latency wise then forcing everyone to a specific region
vassbence
vassbence•11mo ago
I ran the db in 3 regions, us-east-1, eu-central-1 and ap-southeast-1 and specifically ran tests from other regions so that the single region - multi region test is fair so for example from us-west-1 so basically the other coast single-region db was faster than the multi-region for a write+read test simply because it had to do 2 round trips across the whole us instead of just going to us-east-1, doing the db things there and returning one time So for the multi-region setup i would need to run like 5 replicas, and it's not worth it at that point imho