エンジニア採用をキャパシティプランニングしよう

お久しぶりです。id:unlearned です。

会社では上杉で通しています。

このブログを始めた頃は、30歳ぴったりくらいだった気がするのですが、もう40代も半ばです。 冬の寒さも身にしみるようになりました。

今年はCOVID-19のせいで散々でしたね。しかし、せっかくのクリスマスイブです。楽しんでいきましょう。

さて、この記事は、hey アドベントカレンダー2020 の24日目の記事です。

僕は今年の終わり頃から、hey の CTO室 というところでお世話になっていて、エンジニア採用やらなにやらをいろいろ考えたりする仕事をしています。

あ、もちろん考えてるだけではなくて、いろいろやっているんですが、考えるというのはすごく大切なことです。

ご存知かもしれませんが、 弊社(hey社)は今エンジニアを積極採用中でして、来年も良い人たちと一緒に働けたらなと思っています。

さて、今日はエンジニア採用のオペレーションについて考えたいなと思います。

エンジニア採用オペレーションの難しいところ

エンジニア採用の難易度は、市場にいるエンジニアが少ないとか、そういう話だけではなくて、日々のオペレーションもなかなか大変です。

エンジニアの採用ともなると、やはり技術的な側面もちゃんと面接しなければなりません。 そうするとですね、日々ガリガリとコードを書いてるエンジニアの力を借りないといけない。

コードを書くにはすごく集中力が必要で、面接なんてしちゃうと集中力が失われて、それ以降コードを書けなくなったりする。 さらに言うとですね、リリース日程がタイトな場合もあったりして、そういう時にあんまりプレッシャーをかけたくない。

にも関わらずですね、世の「採用頑張るぞ」は、無策なことが多い。 無策はよくない。

21世紀にもなって「食料は現地調達」みたいなところが、我々日本人にはあるんじゃないかなと感じます。 そういう反省はもうこの本で十分です。

人間中心主義でいこう

そもそもね100人くらいの会社で30人採用とか、そういうの大きいことを考えるのはとってもいいことだと思う。

世の中の求人が増えることは、基本的には良いことだと僕は思っている。

いろんな工夫ができる。

エージェントさんにいっぱい紹介してってお願いするのも良い。社内でリファラル採用を進めるのも良いし、自社メディアを立ち上げたりも採用を進めるにあたってはすごく良いことです。

でもじゃあさ、目線を変えるとね、

「社内でそれ受け止めるキャパシティあるの?」

って話です。

よく人間を「リソース」って言葉で表してしまう人がいるけど、僕はあんまりそういう言葉が好きじゃない。

人間はモノでもないし、仕事だけをする機械でもない。

感情があって、家庭があって、母であり、父であり、友であり。 はたまた、時々疲れてたり、荒んでたりもする。 もうね、働きすぎちゃうと、消耗しちゃうんですね。 だから、余裕をもたないといけない。

ちゃんと職場に適切なゆとりをもたらすのが、マネージャーの役割の一つだと僕は思っている訳です。

そうなってくるとですね、採用オペレーションのキャパシティを予測して、適切に人員の配置や、効率化などをしないといけない。

キャパシティプランニング

ここで、やっとエンジニアっぽい話になるんですが、キャパシティプランニングってみなさんご存知でしょうか?

SREチームの方々は当然ご存知だと思います。

Wikipediaのサービスデリバリの説明の中に「キャパシティ管理」として近しい内容が書いてありましたので、引用します。

サービスデリバリ - Wikipedia

開発するサービスが性能要件を満たす為に必要なリソースやスループットを見積もり、サービスレベルに見合った機能とコストを試算する事、さらに運用が開始されたサービスについて定期的な記録を採り、IT資源の枯渇や応答時間の監視などを行い、サービスレベル維持の為の定期的な拡張やメンテナンスをプランニングしていく為のプロセスとして位置づけられている。

以下、ちょっと古い本ですが(なんだもう10年以上前かよぉ、、、)

僕はインフラもやっていたので、こういう本でキャパシティプランニングを学びました。

近年はAWSなどができて、サーバーの調達なんて考えなくて良くなりましたが、 昔は1ヶ月前には発注しておかないといけないとか、そういう事態がよくありまして、インフラエンジニアにとっては、死活問題になる知識でした。

コンピュータ資源のキャパシティプランニングのアイディアは、組織体制のキャパシティプランニングにも活かせそうです。

さて何にせよですね、自組織の体制が、採用プロセスを回せる状態にあるか、事前に予測しておきたい。

採用の全体感をつかむ

採用にはいくつかのフェーズがあります。 ざっとこんな感じかなと思います。

f:id:unlearned:20201223194230p:plain
採用フェーズ

この各フェーズでの数値を取っておくわけです。 来年からどうするかを考えている、リクルーティング担当者は今年の数値をちゃんと把握しておくといいですね。

あくまでも、選考という過程だけに範囲を絞ると、 エントリー数から入社までくらいで考える感じになるかと思います。

(今回は議論から外していますが、オンボーディングはすごく大事です。一番時間もかかりますので、ここはここでちゃんと考えておきましょう)

ゴールから逆算する

さて、選考の各フェーズごとに数値を取っておくと、通過率を出せます。

f:id:unlearned:20201223200353p:plain
各フェーズの通過率

ゴールから逆算することで、シミュレーションができるようになります。

簡単に言うと、選考の各フェーズの通過率の逆数を、採用数から掛けていきます。

下の図は、採用数をN人とした場合のシミュレーションになります。

f:id:unlearned:20201223201035p:plain
逆算

こうすると、最終的に、

  • エントリーがどれくらい必要か
  • 何回面接をする必要があるか
  • 必要な時間数はどれくらいか(面接にどれくらい時間がかかるかわかれば)

など実際の目標値や、負担を定量的に予測できるわけです。

やってみよう

さて、Microsoft ExcelGoogleスプレッドシートなどを取り出してやってみましょう。

来年の採用計画のキャパシティプランニングをして、効率化や面接官の補充など、プロセス改善に役立てましょう!!

しかし...

でもすごくだるいじゃないですか? エンジニアはExcel嫌いですよね。多分。

(僕はちゃんとGoogleスプレッドシートでやりました)

そこで

strife

だるいので、コマンドラインツールを作りました。

STatistical Recruiting Information For Engineers

GOPATHは適切に設定してあると仮定します。

$ go get github.com/unlearned/strife/cmd/strife

としてインストールします。

次に、以下のような感じでjsonファイルを作ります。ファイル名は任意ですが、ここでは、 recruiting_result_2020.json とでもしましょう

{
    "phases": [
    {
        "name": "entry",
        "number": 480
    },
    {
        "name": "document screening",
        "number": 160,
        "average_number_of_hours_spent": 0.2
    },
    {
        "name": "1st interview",
        "number": 80,
        "average_number_of_hours_spent": 1.5
    },
    {
        "name": "2nd interview",
        "number": 40,
        "average_number_of_hours_spent": 1.5
    },
    {
        "name": "3rd interview",
        "number": 20,
        "average_number_of_hours_spent": 1.5
    },
    {
        "name": "offer meeting",
        "number": 15,
        "average_number_of_hours_spent": 1.5
    },
    {
        "name": "join",
        "number": 10
    }
    ]
}
  • name は各フェーズの名前を入れます。
  • number は各フェーズのプロセスを行った回数、もしくは採用された人の数などです。
  • average_number_of_hours_spent はそのフェーズのプロセス1回あたりに何時間かかったかです。

あとは来年採用したい人数を決めましょう。ここでは仮に 30 とします。 そして、次のようにコマンドを叩きます!

$ strife 30 ./recruiting_result_2020.json                                                                                                                                                                                                                                        
## Past Performance ##
|         phase        |      entry      |document screening|   1st interview  |   2nd interview  |   3rd interview  |   offer meeting  |       join      |
|         number       |        480       |        160       |        80        |        40        |        20        |        15        |        10        |
|average hours required|         0        |        0.2       |        1.5       |        1.5       |        1.5       |        1.5       |         0        |

## Prediction ##
|         phase        |      entry      |document screening|   1st interview  |   2nd interview  |   3rd interview  |   offer meeting  |       join      |
|         number       |       1440       |        480       |        240       |        120       |        60        |        45        |        30        |
|average hours required|         0        |        0.2       |        1.5       |        1.5       |        1.5       |        1.5       |         0        |
| total hours required |         0        |        96        |        360       |        180       |        90        |       67.5       |         0        |

terminalで等幅のフォントを使っていれば、綺麗に出力されるかと思います。

これは僕が適当に作った情報ですが、上記より、この架空の会社の過去採用実績から鑑みるに、30人採用するためには、1440人のエントリーが必要ですねというのが見て取れます。 また書類選考だけで96時間、一次面接は240回、360時間かかることがわかります。

と、このように実績からの予測が作れるというわけです。

この予測をもとに、面接できる人を増やしたり、ホットスポットを見つけ効率化を行います。

まとめ

まとめます

  • エンジニア採用のオペレーションはエンジニアに負荷をかける
  • 負荷のかけ過ぎは良くない。人間は道具じゃない
  • 予測し、体制を組み、効率化を行うことをしよう
  • 予測のために
    • 構造を把握し、全体感をつかもう
    • 情報を得よう
    • 情報を利用して逆算しよう
  • スプレッドシートなどでやろう

以下余談

  • STRIFEってのは僕の好きなバンドの名前です
  • 今回Go言語初めて書きました。諸々拙い部分多いかと思いますので、教えていただけると助かります
  • README を書く前に力尽きました。なるはやで書きます
  • recruiting ってuの後にiが入るんですね。コード内に埋め込んでしまいました。なるはやで直します

最後に繰り返します。弊社(hey社)はエンジニアもエンジニア以外も積極採用中ですー。

以上です!良いお年をー