Is there a limit to the number of tags we can use?

The maximum number of tags you can define in the tag inspector is 10001. Clearly instantiating more than 10k objects is not a good idea (but possible) it is technically possible for you to tag most objects differently - however, given that you have to manually create each tag in the tag inspector this becomes unwieldy.

Tags are the fastest method of finding things and appear to operate around O(1) performance.

If you need equivalent performance for lookup but no limit and no need to create tags up front you can write your own script:

   public class Tagger : MonoBehaviour {
        public static Dictionary<string, List<GameObject>> tags = new Dictionary<string, List<GameObject>>();
        public string tag;
        void OnEnable() { //Or Awake if you don't care about enabled state
             if(!tags.ContainsKey(tag)) tags[tag] = new List<GameObject>();
             tags[tag].Add(gameObject);
        }
        void OnDisable() { //Or OnDestroy if using Awake
             tags[tag].Remove(gameObject);
        }
   }

And the equivalent of FindGameObjectsWithTag:

    var matching = Tagger.tags["SomeTag"];

To check the tag:

   if(someObject.GetComponent<Tagger>().tag == "Something")

Or if you prefer with an extension method

  public static class TaggerExtension {
       public static string GetTagValue(this GameObject go) { return go.GetComponent<Tagger>().tag; }
       public static string GetTagValue(this Component co) { return co.GetComponent<Tagger>().tag; }
  }

Then

    if(someObject.GetTagValue() == "sometag")