this post was submitted on 28 Sep 2025
225 points (98.3% liked)

Programming

23570 readers
81 users here now

Welcome to the main community in programming.dev! Feel free to post anything relating to programming here!

Cross posting is strongly encouraged in the instance. If you feel your post or another person's post makes sense in another community cross post into it.

Hope you enjoy the instance!

Rules

Rules

  • Follow the programming.dev instance rules
  • Keep content related to programming in some way
  • If you're posting long videos try to add in some form of tldr for those who don't want to watch videos

Wormhole

Follow the wormhole through a path of communities !webdev@programming.dev



founded 2 years ago
MODERATORS
 

Context: Searching for a new senior level software development job over a 9 week period in summer 2025.

  • Focused mostly on data engineering and backend roles that are in-person or hybrid in the SF Bay Area.
  • Leads from recruiters on LinkedIn were much more likely to lead to interviews+offers.
  • The winning offer came through my personal network.
  • I mostly used Hiring.cafe for prospecting. They're a scraper with an interface I didn't hate.
top 29 comments
sorted by: hot top controversial new old
[–] mesamunefire@piefed.social 35 points 1 month ago* (last edited 1 month ago) (1 children)

Interesting breakdown. Its a hard market.

My last Two jobs were both referrals.

[–] Psythik@lemmy.world 11 points 1 month ago

Tell me about it. Took me 3x as many applications to land two interviews, and I wasn't even looking for a specific field. My only requirement was $20/hr or more, the bare minimum needed to survive.

Finally settled on a $19/hr job after a six month struggle. I can't afford groceries but at least I won't go homeless.

[–] aziz@functional.cafe 22 points 1 month ago (2 children)

@deegeese you applied 151 times? Are you in the USA? At least me in Europe / France / Paris, I do not apply more than three per round

[–] deegeese@sopuli.xyz 11 points 1 month ago (2 children)

If half of your applications never reply even to reject, when is the next round? Need more activity to keep your pipeline full.

I generally didn’t have more than 3 or so going on at once in the later stages.

[–] HelloRoot@lemy.lol 15 points 1 month ago* (last edited 1 month ago) (3 children)

I guess the approach is different.

I do 1-3 high quality applications and get invites to an in person meeting for all of them. Often times getting an offer from all as well and then I decide. Each one takes about 3-5 days in total including research on the company, completely custom cover letter, proof reading, getting feedback from friends that work in the field, and hand picked example code projects from my repo or even throwing together a quick prototype related to the job offer. Been doing it this way for 12 years.

If you do a shotgun approach with 160 low quality ones then it doesn't surprise me that half don't reply.

If I did 160 applications the way I usually do them, I would literally be writing them for nearly 2 (two!) years... thats the only reason I assume yours are low quality.

[–] TehPers@beehaw.org 8 points 1 month ago* (last edited 1 month ago) (1 children)

This sounds to me like we need to move to Germany. It's not uncommon for people in the US to apply to hundreds, or even thousands, of jobs and get a single-digit number of interviews (or offers, in industries where interviewing is uncommon) out of it, regardless of effort put into the application. Most applications are rejected before a human ever reads them.

[–] HelloRoot@lemy.lol 2 points 1 month ago* (last edited 1 month ago) (1 children)

To be fair, I only worked at small/medium companies ( <100 people ) and a quarter of the time I had a contact there from some networking event.

[–] balrog@programming.dev 11 points 1 month ago (1 children)

That's an entirely different situation then. That's just the power of networking

Networking is 100% the easiest way to get a job. The people that have networking don't need advice. 99% of the job hunting advice is with the assumption you don't have a network you can rely on for finding jobs. Because if you did, you wouldn't be having trouble finding a job

[–] HelloRoot@lemy.lol 1 points 1 month ago

a quarter of the time

[–] Scolding7300@lemmy.world 7 points 1 month ago (2 children)

I'm pretty sure some places would just skip over your application (with some probability) because the sheer amount of applications they receive

[–] Tanoh@lemmy.world 8 points 1 month ago* (last edited 1 month ago)

Oh yes.

As the old joke goes:

"Well, we don't want our future employee to be unlucky... *grabs half of the printed applications and tosses them in the trash*"

[–] sheogorath@lemmy.world 4 points 1 month ago

My friend who works in marketing usually try to find out the hiring manager and also emailed them directly while also providing something similar to the commenter above (3-month marketing and content plan instead of a sample project) and it's basically 100% success rate for getting a response for him.

[–] favoredponcho@lemmy.zip 4 points 1 month ago (1 children)

How old are you and when was the last time you looked for a job?

[–] HelloRoot@lemy.lol 3 points 1 month ago

Been doing it this way for 12 years.

you can guess from this.

Last time was this year.

[–] aziz@functional.cafe 2 points 1 month ago

@deegeese it was a while back before covid, and stuff, And it rarely bounce at the first round, but I target precisely each email. Head hunters help too.

Beautiful graph. Good luck pal.

[–] JustEnoughDucks@feddit.nl 1 points 1 month ago

Really depends.

I am in belgium and for Electronics engineering, there are very few jobs and a lot of candidates (and notoriously difficult to get around via car in belgium). I have 5 year of experience, recommendation letters, and good references.

20 applications. 9 ghosted, 4 auto rejections, 2 declined by me as not a good job, 1 rejection after hiring manager interview (too far, 1.5+ hour one way in traffic and they had closer candidates just as good), 2 rejections after final interview (one ghosted, the other wanted to take both me and the other candidate on, but couldn't), 2 offers.

It is definitely rough in the engineering industry outside of defense.

On the flip side, I see hundreds of software jobs here and hundreds of electrical/building automation jobs.

It seems like personal networks are still, by far, the most likely way to get a job. Having an internal reference helps you bypass so many filters.

It makes sense for employers, too, because a confirmed human that really wants the job is already better than the majority of the crap they have to sift through.

[–] lostme@lemmy.world 11 points 1 month ago

man.... over 400 applications, something like 5 interviews, no offers, i gave up ._. entry level is fucked

[–] andioop@programming.dev 9 points 1 month ago

Hey, congratulations on the employment!

[–] paequ2@lemmy.today 6 points 1 month ago* (last edited 1 month ago)

Interesting. I recently was job hunting in 2025, January to June. In US. I was looking for remote only jobs.

My stats:

  • Number of jobs applied to: 53
  • Number of rejections: 52
  • Number of jobs that rejected me with an internal referral: 4
  • Number of offers: 1
  • Search duration: 24 weeks

I guess I was applying to 2.2 per week. I was also mixing in studying and preparing for interviews during that time. Still slow though.

16 applications per week. Nice! Good job!

[–] Kissaki@programming.dev 4 points 1 month ago (1 children)

I find this kind of graph a bit misleading/ambiguous. I intuitively want to follow horizontal association between in and out. For example, Recruiter at the bottom splits into three at the bottom.

Not sure if there's a better way to do this. Disconnect in-bar and out-bar with a condensed point/circle to indicate non-conformity?

[–] deegeese@sopuli.xyz 2 points 1 month ago (1 children)

If you know something better I’d like to give it a spin.

[–] squaresinger@lemmy.world 2 points 1 month ago (1 children)

The better option is to keep colors from the original input stream for the flows instead of making the flows an uniform color.

In the input on the left you have pink, green and blue.

Keep these colors throughout the graph.

Except of the input, all of the other stages only ever split up and never merge, so keeping this single set of colors is enough.

The other option would be to get rid of the "leads" stage, since it actually doesn't change any state. All the other stages are an action that happens (e.g. "Applied" changes the state of the application from being just a lead to being an open application and it also filters out data for being e.g. abandoned). But the "leads" stage means the same thing as the first stage. So drop the "leads" stage and instead make flows go from all three input stages directly into "bad lead", "abandoned" or "applied".

Combine both to get the best result.

[–] deegeese@sopuli.xyz 2 points 1 month ago (1 children)

Is there any site that does this?

[–] squaresinger@lemmy.world 1 points 1 month ago (1 children)

Don't know if there's a ready-made site for stuff like that, but it's not hard to do.

Here's a quick and dirty AI generated piece of trash code as a proof of concept:

# sankey_hiring_funnel_direct.py
# Requires: plotly
# Install: pip install plotly

import plotly.graph_objects as go

# Node labels (unique)
labels = [
    "Network",            # 0
    "Hiring.cafe",        # 1
    "Abandoned Lead",     # 2
    "Applied",            # 3
    "Rejected",           # 4
    "No Response",        # 5
    "Screener",           # 6
    "Rejected by Screen", # 7
    "Full Round",         # 8
    "Rejected by Panel",  # 9
    "Offer",              #10
    "Accepted",           #11
    "Declined"            #12
]

# Colors for the two source groups (consistent)
network_color = "rgba(31,119,180,0.8)"      # blue-ish
hiring_color  = "rgba(255,127,14,0.8)"      # orange-ish

sources = []
targets = []
values  = []
link_colors = []

def add_link(src_idx, tgt_idx, val, color):
    sources.append(src_idx)
    targets.append(tgt_idx)
    values.append(val)
    link_colors.append(color)

# Direct flows from Network and Hiring.cafe into Abandoned Lead and Applied
add_link(0, 2, 1, network_color)    # Network -> Abandoned Lead (1)
add_link(1, 2, 58, hiring_color)    # Hiring.cafe -> Abandoned Lead (58)
add_link(0, 3, 11, network_color)   # Network -> Applied (11)
add_link(1, 3, 70, hiring_color)    # Hiring.cafe -> Applied (70)

# Applied -> Rejected, No Response, Screener (split by original group)
add_link(3, 4, 5, network_color)    # Applied -> Rejected (network 5)
add_link(3, 4, 40, hiring_color)    # Applied -> Rejected (hiring 40)
add_link(3, 5, 3, network_color)    # Applied -> No Response (network 3)
add_link(3, 5, 15, hiring_color)    # Applied -> No Response (hiring 15)
add_link(3, 6, 4, network_color)    # Applied -> Screener (network 4)
add_link(3, 6, 15, hiring_color)    # Applied -> Screener (hiring 15)

# Screener -> Rejected by Screen, Full Round
add_link(6, 7, 1, network_color)    # Screener -> Rejected by Screen (network 1)
add_link(6, 7, 5, hiring_color)     # Screener -> Rejected by Screen (hiring 5)
add_link(6, 8, 3, network_color)    # Screener -> Full Round (network 3)
add_link(6, 8, 10, hiring_color)    # Screener -> Full Round (hiring 10)

# Full Round -> Rejected by Panel, Offer
add_link(8, 9, 1, network_color)    # Full Round -> Rejected by Panel (network 1)
add_link(8, 9, 7, hiring_color)     # Full Round -> Rejected by Panel (hiring 7)
add_link(8, 10, 2, network_color)   # Full Round -> Offer (network 2)
add_link(8, 10, 3, hiring_color)    # Full Round -> Offer (hiring 3)

# Offer -> Accepted, Declined
add_link(10, 11, 1, network_color)  # Offer -> Accepted (network 1)
add_link(10, 12, 1, network_color)  # Offer -> Declined (network 1)
add_link(10, 12, 3, hiring_color)   # Offer -> Declined (hiring 3)

# Sanity check
assert len(sources) == len(targets) == len(values) == len(link_colors)

# Node colors (visual guidance)
node_colors = [
    "rgba(31,119,180,0.9)",   # Network
    "rgba(255,127,14,0.9)",   # Hiring.cafe
    "rgba(220,220,220,0.9)",  # Abandoned Lead
    "rgba(200,200,200,0.9)",  # Applied
    "rgba(220,180,180,0.9)",  # Rejected
    "rgba(200,200,220,0.9)",  # No Response
    "rgba(200,220,200,0.9)",  # Screener
    "rgba(255,200,200,0.9)",  # Rejected by Screen
    "rgba(210,210,255,0.9)",  # Full Round
    "rgba(240,200,220,0.9)",  # Rejected by Panel
    "rgba(200,255,200,0.9)",  # Offer
    "rgba(140,255,140,0.9)",  # Accepted
    "rgba(255,140,140,0.9)"   # Declined
]

fig = go.Figure(data=[go.Sankey(
    node=dict(
        pad=18,
        thickness=18,
        line=dict(color="black", width=0.5),
        label=labels,
        color=node_colors
    ),
    link=dict(
        source=sources,
        target=targets,
        value=values,
        color=link_colors,
        hovertemplate='%{source.label} → %{target.label}: %{value}<extra></extra>'
    )
)])

fig.update_layout(
    title_text="Hiring funnel Sankey — direct source flows (no Leads node)",
    font_size=12,
    height=700,
    margin=dict(l=20, r=20, t=60, b=20)
)

fig.show()

# To save as interactive HTML:
# fig.write_html("sankey_hiring_funnel_direct.html", include_plotlyjs='cdn')

Couldn't be bothered to write this by hand for just an online comment. There's enough that can be improved with this, but I think it's ok to show how it can be done quite easily.

[–] deegeese@sopuli.xyz 1 points 1 month ago (1 children)

Thanks for sharing that. Seems like a promising vis technique but would work better with fewer final states than I used for a regular Sankey.

[–] squaresinger@lemmy.world 1 points 1 month ago

I'm sure it's possible to move the final states to the middle positions like you did. But I didn't want to invest more time.

[–] jcs@lemmy.world 2 points 1 month ago (1 children)

It only takes 1 opportunity to change your life.

[–] Kissaki@programming.dev 8 points 1 month ago

For better or worse