Yesterday I was asked to integrate Sendgrid with our analytics server over cURL in a cronjob.
Not only had I never used Sendgrid before or even seen the codebase for our analytics server, I've never used cURL Multi before - so I was walking in knowing nothing.
I said it would take me "about 2 days", which seemed "fair" to my manager, in the end it only took me about 5 hours, so they were happy to get it early and I had all the debug time I needed.
I then took a look at the analytics and the database makeup and a break down of tasks which I needed to accomplish were as thus (I was told by my manager to make product_name work with Sendgrid - that's it):
- Connect to the database
- Query recently added "leads"
- Grab lead email information and funnel_id
- Grab template and cache it (multiple emails can use the same template, and there are standard templates, making a query for every single template would make database IO a real issue)
- Build up the emails in to an Array, complete with template reference and replaced [TAGS] (full name, etc) required by each individual email
- Actually initialize cURL, create the multi_curl_init objects and loop through, check each request for the {success} JSON object returned by Sendgrid and reschedule / show an error in our logs for that email funnel
- Clean up after ourselves, rinse and repeat 10 minutes later for the next lot of leads.
- debug
In all honesty, the only way I knew the length of time required was breaking down an estimate for each individual task and then adding them all up and doubling it. It was an "intuitive guess".
As you get older (more experienced) you become less concerned with overestimation. When you're young and ambitious you think that a) you can do it faster than you really can and b) it's bad to say it'll take 2 days when really you think you can do it in 1. a) you can't and b) people don't normally question your overestimates.
Also, try to think things through. Ask questions. Discover those subtle missing requirements that haven't been communicated yet. Try to picture how it will fit into the system and imagine why that might go wrong. If it's a bigger feature break it into parts and (over)estimate each of those.
Be thoughtful, overestimate and be honest (especially with yourself).
If it's a big project then chop it up into deliverables, so you can monitor your estimates along the way.
..there's a lot more but something to get you started.
(if you have to deliver on your estimate - double it :-). When you double your estimate - make sure you don't work to your doubled estimates - otherwise you'll have to double it again :-) )
Anyway, the only way to give a valid estimate is to break down the task as much as you possibly can and to assign risk to each small task. Build a spreadsheet and break down every task into the smallest possible unit, and assign a risk rating to it. Any tasks that are high risk should be estimated as a range, rather than a fixed time. Even with this advice you'll still get things wrong, but it's impossible not to. It's the nature of estimating.
The best advice I can give you is to stick to your guns and estimate for how long it will take YOU to do a task. If people still argue, then tough. As rightly pointed out by adios, more experienced devs/pm's will happily overestimate and will fight their corner to say that this is how long a task takes. If you are honest with yourself on how long a task will take then you will find it much easier to stick to your guns when someone complaints that "an easy task" shouldn't take as long as you've said.
Never gather it, until you know how it's going to be used.
Who is asking you to estimate, and what are they going to do with those numbers?
Until you explore and understand the answers to those kinds of questions, it's irresponsible to try to satisfy the request.
If you like the answers you get, then give the best data you can. If the answers you get suck, then you need to try to change how people are behaving. If you can't, then maybe you need a new job.